merge from 3.0
This commit is contained in:
commit
83eacf8d07
|
@ -53,12 +53,12 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct SColumnDataAgg {
|
typedef struct SColumnDataAgg {
|
||||||
int16_t colId;
|
int16_t colId;
|
||||||
int64_t sum;
|
|
||||||
int64_t max;
|
|
||||||
int64_t min;
|
|
||||||
int16_t maxIndex;
|
int16_t maxIndex;
|
||||||
int16_t minIndex;
|
int16_t minIndex;
|
||||||
int16_t numOfNull;
|
int16_t numOfNull;
|
||||||
|
int64_t sum;
|
||||||
|
int64_t max;
|
||||||
|
int64_t min;
|
||||||
} SColumnDataAgg;
|
} SColumnDataAgg;
|
||||||
|
|
||||||
typedef struct SDataBlockInfo {
|
typedef struct SDataBlockInfo {
|
||||||
|
|
|
@ -135,8 +135,8 @@ typedef struct {
|
||||||
#define TD_VTYPE_PARTS 4 // 8 bits / TD_VTYPE_BITS = 4
|
#define TD_VTYPE_PARTS 4 // 8 bits / TD_VTYPE_BITS = 4
|
||||||
#define TD_VTYPE_OPTR 3 // TD_VTYPE_PARTS - 1, utilize to get remainder
|
#define TD_VTYPE_OPTR 3 // TD_VTYPE_PARTS - 1, utilize to get remainder
|
||||||
|
|
||||||
#define TD_BITMAP_BYTES(cnt) (ceil((double)cnt / TD_VTYPE_PARTS))
|
#define TD_BITMAP_BYTES(cnt) (ceil((double)(cnt) / TD_VTYPE_PARTS))
|
||||||
#define TD_BIT_TO_BYTES(cnt) (ceil((double)cnt / 8))
|
#define TD_BIT_TO_BYTES(cnt) (ceil((double)(cnt) / 8))
|
||||||
|
|
||||||
int32_t tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version);
|
int32_t tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, schema_ver_t version);
|
||||||
void tdDestroyTSchemaBuilder(STSchemaBuilder *pBuilder);
|
void tdDestroyTSchemaBuilder(STSchemaBuilder *pBuilder);
|
||||||
|
@ -365,6 +365,7 @@ static FORCE_INLINE void tdCopyColOfRowBySchema(SDataRow dst, STSchema *pDstSche
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// ----------------- Data column structure
|
// ----------------- Data column structure
|
||||||
|
// SDataCol arrangement: data => bitmap => dataOffset
|
||||||
typedef struct SDataCol {
|
typedef struct SDataCol {
|
||||||
int8_t type; // column type
|
int8_t type; // column type
|
||||||
uint8_t bitmap : 1; // 0: has bitmap if has NULL/NORM rows, 1: no bitmap if all rows are NORM
|
uint8_t bitmap : 1; // 0: has bitmap if has NULL/NORM rows, 1: no bitmap if all rows are NORM
|
||||||
|
|
|
@ -930,6 +930,21 @@ typedef struct {
|
||||||
char data[];
|
char data[];
|
||||||
} SRetrieveMetaTableRsp;
|
} SRetrieveMetaTableRsp;
|
||||||
|
|
||||||
|
typedef struct SExplainExecInfo {
|
||||||
|
uint64_t startupCost;
|
||||||
|
uint64_t totalCost;
|
||||||
|
uint64_t numOfRows;
|
||||||
|
void *verboseInfo;
|
||||||
|
} SExplainExecInfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t numOfPlans;
|
||||||
|
SExplainExecInfo *subplanInfo;
|
||||||
|
} SExplainRsp;
|
||||||
|
|
||||||
|
int32_t tSerializeSExplainRsp(void* buf, int32_t bufLen, SExplainRsp* pRsp);
|
||||||
|
int32_t tDeserializeSExplainRsp(void* buf, int32_t bufLen, SExplainRsp* pRsp);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char fqdn[TSDB_FQDN_LEN]; // end point, hostname:port
|
char fqdn[TSDB_FQDN_LEN]; // end point, hostname:port
|
||||||
int32_t port;
|
int32_t port;
|
||||||
|
@ -1067,6 +1082,7 @@ typedef struct SSubQueryMsg {
|
||||||
uint64_t taskId;
|
uint64_t taskId;
|
||||||
int64_t refId;
|
int64_t refId;
|
||||||
int8_t taskType;
|
int8_t taskType;
|
||||||
|
int8_t explain;
|
||||||
uint32_t sqlLen; // the query sql,
|
uint32_t sqlLen; // the query sql,
|
||||||
uint32_t phyLen;
|
uint32_t phyLen;
|
||||||
char msg[];
|
char msg[];
|
||||||
|
|
|
@ -188,6 +188,7 @@ enum {
|
||||||
TD_DEF_MSG_TYPE(TDMT_VND_SHOW_TABLES_FETCH, "vnode-show-tables-fetch", SVShowTablesFetchReq, SVShowTablesFetchRsp)
|
TD_DEF_MSG_TYPE(TDMT_VND_SHOW_TABLES_FETCH, "vnode-show-tables-fetch", SVShowTablesFetchReq, SVShowTablesFetchRsp)
|
||||||
TD_DEF_MSG_TYPE(TDMT_VND_QUERY_CONTINUE, "vnode-query-continue", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_VND_QUERY_CONTINUE, "vnode-query-continue", NULL, NULL)
|
||||||
TD_DEF_MSG_TYPE(TDMT_VND_QUERY_HEARTBEAT, "vnode-query-heartbeat", NULL, NULL)
|
TD_DEF_MSG_TYPE(TDMT_VND_QUERY_HEARTBEAT, "vnode-query-heartbeat", NULL, NULL)
|
||||||
|
TD_DEF_MSG_TYPE(TDMT_VND_EXPLAIN, "vnode-explain", NULL, NULL)
|
||||||
|
|
||||||
TD_DEF_MSG_TYPE(TDMT_VND_SUBSCRIBE, "vnode-subscribe", SMVSubscribeReq, SMVSubscribeRsp)
|
TD_DEF_MSG_TYPE(TDMT_VND_SUBSCRIBE, "vnode-subscribe", SMVSubscribeReq, SMVSubscribeRsp)
|
||||||
TD_DEF_MSG_TYPE(TDMT_VND_CONSUME, "vnode-consume", SMqCVConsumeReq, SMqCVConsumeRsp)
|
TD_DEF_MSG_TYPE(TDMT_VND_CONSUME, "vnode-consume", SMqCVConsumeReq, SMqCVConsumeRsp)
|
||||||
|
|
|
@ -147,20 +147,20 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// basic info
|
// basic info
|
||||||
int8_t rowType;
|
int8_t rowType;
|
||||||
int16_t sver;
|
schema_ver_t sver;
|
||||||
STSRow *pBuf;
|
STSRow *pBuf;
|
||||||
|
|
||||||
// extended info
|
// extended info
|
||||||
int32_t flen;
|
int32_t flen;
|
||||||
int16_t nBoundCols;
|
col_id_t nBoundCols;
|
||||||
int16_t nCols;
|
col_id_t nCols;
|
||||||
int16_t nBitmaps;
|
col_id_t nBitmaps;
|
||||||
int16_t nBoundBitmaps;
|
col_id_t nBoundBitmaps;
|
||||||
int32_t offset;
|
int32_t offset;
|
||||||
void *pBitmap;
|
void *pBitmap;
|
||||||
void *pOffset;
|
void *pOffset;
|
||||||
int32_t extendedRowSize;
|
int32_t extendedRowSize;
|
||||||
} SRowBuilder;
|
} SRowBuilder;
|
||||||
|
|
||||||
#define TD_ROW_HEAD_LEN (sizeof(STSRow))
|
#define TD_ROW_HEAD_LEN (sizeof(STSRow))
|
||||||
|
@ -448,9 +448,9 @@ static FORCE_INLINE int32_t tdSRowSetExtendedInfo(SRowBuilder *pBuilder, int32_t
|
||||||
}
|
}
|
||||||
#ifdef TD_SUPPORT_BITMAP
|
#ifdef TD_SUPPORT_BITMAP
|
||||||
// the primary TS key is stored separatedly
|
// the primary TS key is stored separatedly
|
||||||
pBuilder->nBitmaps = (int16_t)TD_BITMAP_BYTES(pBuilder->nCols - 1);
|
pBuilder->nBitmaps = (col_id_t)TD_BITMAP_BYTES(pBuilder->nCols - 1);
|
||||||
if (nBoundCols > 0) {
|
if (nBoundCols > 0) {
|
||||||
pBuilder->nBoundBitmaps = (int16_t)TD_BITMAP_BYTES(pBuilder->nBoundCols - 1);
|
pBuilder->nBoundBitmaps = (col_id_t)TD_BITMAP_BYTES(pBuilder->nBoundCols - 1);
|
||||||
} else {
|
} else {
|
||||||
pBuilder->nBoundBitmaps = 0;
|
pBuilder->nBoundBitmaps = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,6 +146,7 @@ typedef struct {
|
||||||
#define IS_FLOAT_TYPE(_t) ((_t) == TSDB_DATA_TYPE_FLOAT || (_t) == TSDB_DATA_TYPE_DOUBLE)
|
#define IS_FLOAT_TYPE(_t) ((_t) == TSDB_DATA_TYPE_FLOAT || (_t) == TSDB_DATA_TYPE_DOUBLE)
|
||||||
|
|
||||||
#define IS_NUMERIC_TYPE(_t) ((IS_SIGNED_NUMERIC_TYPE(_t)) || (IS_UNSIGNED_NUMERIC_TYPE(_t)) || (IS_FLOAT_TYPE(_t)))
|
#define IS_NUMERIC_TYPE(_t) ((IS_SIGNED_NUMERIC_TYPE(_t)) || (IS_UNSIGNED_NUMERIC_TYPE(_t)) || (IS_FLOAT_TYPE(_t)))
|
||||||
|
#define IS_MATHABLE_TYPE(_t) (IS_NUMERIC_TYPE(_t) || (_t) == (TSDB_DATA_TYPE_BOOL) || (_t) == (TSDB_DATA_TYPE_TIMESTAMP))
|
||||||
|
|
||||||
#define IS_VALID_TINYINT(_t) ((_t) > INT8_MIN && (_t) <= INT8_MAX)
|
#define IS_VALID_TINYINT(_t) ((_t) > INT8_MIN && (_t) <= INT8_MAX)
|
||||||
#define IS_VALID_SMALLINT(_t) ((_t) > INT16_MIN && (_t) <= INT16_MAX)
|
#define IS_VALID_SMALLINT(_t) ((_t) > INT16_MIN && (_t) <= INT16_MAX)
|
||||||
|
|
|
@ -59,6 +59,7 @@ int32_t taosVariantDumpEx(SVariant *pVariant, char *payload, int16_t type, bool
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int32_t taosVariantTypeSetType(SVariant *pVariant, char type);
|
int32_t taosVariantTypeSetType(SVariant *pVariant, char type);
|
||||||
|
char * taosVariantGet(SVariant *pVar, int32_t type);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,14 @@
|
||||||
#include "tmsg.h"
|
#include "tmsg.h"
|
||||||
#include "plannodes.h"
|
#include "plannodes.h"
|
||||||
|
|
||||||
|
typedef struct SExplainCtx SExplainCtx;
|
||||||
|
|
||||||
int32_t qExecCommand(SNode* pStmt, SRetrieveTableRsp** pRsp);
|
int32_t qExecCommand(SNode* pStmt, SRetrieveTableRsp** pRsp);
|
||||||
|
|
||||||
int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp);
|
int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp);
|
||||||
|
int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int32_t startTs);
|
||||||
|
int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp);
|
||||||
|
int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp);
|
||||||
|
void qExplainFreeCtx(SExplainCtx *pCtx);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -174,6 +174,8 @@ void** qReleaseTask(void* pMgmt, void* pQInfo, bool freeHandle);
|
||||||
|
|
||||||
void qProcessFetchRsp(void* parent, struct SRpcMsg* pMsg, struct SEpSet* pEpSet);
|
void qProcessFetchRsp(void* parent, struct SRpcMsg* pMsg, struct SEpSet* pEpSet);
|
||||||
|
|
||||||
|
int32_t qGetExplainExecInfo(qTaskInfo_t tinfo, int32_t *resNum, SExplainExecInfo **pRes);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,7 +36,7 @@ typedef struct SFuncExecEnv {
|
||||||
|
|
||||||
typedef bool (*FExecGetEnv)(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
typedef bool (*FExecGetEnv)(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
typedef bool (*FExecInit)(struct SqlFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo);
|
typedef bool (*FExecInit)(struct SqlFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo);
|
||||||
typedef void (*FExecProcess)(struct SqlFunctionCtx *pCtx);
|
typedef int32_t (*FExecProcess)(struct SqlFunctionCtx *pCtx);
|
||||||
typedef void (*FExecFinalize)(struct SqlFunctionCtx *pCtx);
|
typedef void (*FExecFinalize)(struct SqlFunctionCtx *pCtx);
|
||||||
typedef int32_t (*FScalarExecProcess)(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
typedef int32_t (*FScalarExecProcess)(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
|
|
||||||
|
@ -154,7 +154,9 @@ typedef struct SResultDataInfo {
|
||||||
int32_t interBufSize;
|
int32_t interBufSize;
|
||||||
} SResultDataInfo;
|
} SResultDataInfo;
|
||||||
|
|
||||||
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
|
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
|
||||||
|
#define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowEntryInfo)))
|
||||||
|
#define DATA_SET_FLAG ',' // to denote the output area has data, not null value
|
||||||
|
|
||||||
typedef struct SInputColumnInfoData {
|
typedef struct SInputColumnInfoData {
|
||||||
int32_t totalRows; // total rows in current columnar data
|
int32_t totalRows; // total rows in current columnar data
|
||||||
|
@ -192,7 +194,8 @@ typedef struct SqlFunctionCtx {
|
||||||
int32_t numOfParams;
|
int32_t numOfParams;
|
||||||
SVariant param[4]; // input parameter, e.g., top(k, 20), the number of results for top query is kept in param
|
SVariant param[4]; // input parameter, e.g., top(k, 20), the number of results for top query is kept in param
|
||||||
int64_t *ptsList; // corresponding timestamp array list
|
int64_t *ptsList; // corresponding timestamp array list
|
||||||
void *ptsOutputBuf; // corresponding output buffer for timestamp of each result, e.g., top/bottom*/
|
SColumnInfoData *pTsOutput; // corresponding output buffer for timestamp of each result, e.g., top/bottom*/
|
||||||
|
int32_t offset;
|
||||||
SVariant tag;
|
SVariant tag;
|
||||||
struct SResultRowEntryInfo *resultInfo;
|
struct SResultRowEntryInfo *resultInfo;
|
||||||
SSubsidiaryResInfo subsidiaryRes;
|
SSubsidiaryResInfo subsidiaryRes;
|
||||||
|
|
|
@ -132,6 +132,7 @@ bool fmIsStringFunc(int32_t funcId);
|
||||||
bool fmIsDatetimeFunc(int32_t funcId);
|
bool fmIsDatetimeFunc(int32_t funcId);
|
||||||
bool fmIsTimelineFunc(int32_t funcId);
|
bool fmIsTimelineFunc(int32_t funcId);
|
||||||
bool fmIsTimeorderFunc(int32_t funcId);
|
bool fmIsTimeorderFunc(int32_t funcId);
|
||||||
|
bool fmIsPseudoColumnFunc(int32_t funcId);
|
||||||
bool fmIsWindowPseudoColumnFunc(int32_t funcId);
|
bool fmIsWindowPseudoColumnFunc(int32_t funcId);
|
||||||
bool fmIsWindowClauseFunc(int32_t funcId);
|
bool fmIsWindowClauseFunc(int32_t funcId);
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,8 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_PHYSICAL_PLAN_SORT,
|
QUERY_NODE_PHYSICAL_PLAN_SORT,
|
||||||
QUERY_NODE_PHYSICAL_PLAN_INTERVAL,
|
QUERY_NODE_PHYSICAL_PLAN_INTERVAL,
|
||||||
QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW,
|
QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW,
|
||||||
|
QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW,
|
||||||
|
QUERY_NODE_PHYSICAL_PLAN_PARTITION,
|
||||||
QUERY_NODE_PHYSICAL_PLAN_DISPATCH,
|
QUERY_NODE_PHYSICAL_PLAN_DISPATCH,
|
||||||
QUERY_NODE_PHYSICAL_PLAN_INSERT,
|
QUERY_NODE_PHYSICAL_PLAN_INSERT,
|
||||||
QUERY_NODE_PHYSICAL_SUBPLAN,
|
QUERY_NODE_PHYSICAL_SUBPLAN,
|
||||||
|
@ -213,16 +215,16 @@ typedef enum EDealRes {
|
||||||
} EDealRes;
|
} EDealRes;
|
||||||
|
|
||||||
typedef EDealRes (*FNodeWalker)(SNode* pNode, void* pContext);
|
typedef EDealRes (*FNodeWalker)(SNode* pNode, void* pContext);
|
||||||
void nodesWalkNode(SNodeptr pNode, FNodeWalker walker, void* pContext);
|
void nodesWalkExpr(SNodeptr pNode, FNodeWalker walker, void* pContext);
|
||||||
void nodesWalkList(SNodeList* pList, FNodeWalker walker, void* pContext);
|
void nodesWalkExprs(SNodeList* pList, FNodeWalker walker, void* pContext);
|
||||||
void nodesWalkNodePostOrder(SNodeptr pNode, FNodeWalker walker, void* pContext);
|
void nodesWalkExprPostOrder(SNodeptr pNode, FNodeWalker walker, void* pContext);
|
||||||
void nodesWalkListPostOrder(SNodeList* pList, FNodeWalker walker, void* pContext);
|
void nodesWalkExprsPostOrder(SNodeList* pList, FNodeWalker walker, void* pContext);
|
||||||
|
|
||||||
typedef EDealRes (*FNodeRewriter)(SNode** pNode, void* pContext);
|
typedef EDealRes (*FNodeRewriter)(SNode** pNode, void* pContext);
|
||||||
void nodesRewriteNode(SNode** pNode, FNodeRewriter rewriter, void* pContext);
|
void nodesRewriteExpr(SNode** pNode, FNodeRewriter rewriter, void* pContext);
|
||||||
void nodesRewriteList(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
|
void nodesRewriteExprs(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
|
||||||
void nodesRewriteNodePostOrder(SNode** pNode, FNodeRewriter rewriter, void* pContext);
|
void nodesRewriteExprPostOrder(SNode** pNode, FNodeRewriter rewriter, void* pContext);
|
||||||
void nodesRewriteListPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
|
void nodesRewriteExprsPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* pContext);
|
||||||
|
|
||||||
bool nodesEqualNode(const SNodeptr a, const SNodeptr b);
|
bool nodesEqualNode(const SNodeptr a, const SNodeptr b);
|
||||||
|
|
||||||
|
@ -237,6 +239,8 @@ int32_t nodesListToString(const SNodeList* pList, bool format, char** pStr, int3
|
||||||
int32_t nodesStringToList(const char* pStr, SNodeList** pList);
|
int32_t nodesStringToList(const char* pStr, SNodeList** pList);
|
||||||
|
|
||||||
int32_t nodesNodeToSQL(SNode *pNode, char *buf, int32_t bufSize, int32_t *len);
|
int32_t nodesNodeToSQL(SNode *pNode, char *buf, int32_t bufSize, int32_t *len);
|
||||||
|
char *nodesGetNameFromColumnNode(SNode *pNode);
|
||||||
|
int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,7 @@ typedef struct SWindowLogicNode {
|
||||||
SFillNode* pFill;
|
SFillNode* pFill;
|
||||||
int64_t sessionGap;
|
int64_t sessionGap;
|
||||||
SNode* pTspk;
|
SNode* pTspk;
|
||||||
|
SNode* pStateExpr;
|
||||||
} SWindowLogicNode;
|
} SWindowLogicNode;
|
||||||
|
|
||||||
typedef struct SSortLogicNode {
|
typedef struct SSortLogicNode {
|
||||||
|
@ -194,11 +195,20 @@ typedef struct SSystemTableScanPhysiNode {
|
||||||
int32_t accountId;
|
int32_t accountId;
|
||||||
} SSystemTableScanPhysiNode;
|
} SSystemTableScanPhysiNode;
|
||||||
|
|
||||||
|
typedef enum EScanRequired {
|
||||||
|
SCAN_REQUIRED_DATA_NO_NEEDED = 1,
|
||||||
|
SCAN_REQUIRED_DATA_STATIS_NEEDED,
|
||||||
|
SCAN_REQUIRED_DATA_ALL_NEEDED,
|
||||||
|
SCAN_REQUIRED_DATA_DISCARD,
|
||||||
|
} EScanRequired;
|
||||||
|
|
||||||
typedef struct STableScanPhysiNode {
|
typedef struct STableScanPhysiNode {
|
||||||
SScanPhysiNode scan;
|
SScanPhysiNode scan;
|
||||||
uint8_t scanFlag; // denotes reversed scan of data or not
|
uint8_t scanFlag; // denotes reversed scan of data or not
|
||||||
STimeWindow scanRange;
|
STimeWindow scanRange;
|
||||||
double ratio;
|
double ratio;
|
||||||
|
EScanRequired scanRequired;
|
||||||
|
SNodeList* pScanReferFuncs;
|
||||||
} STableScanPhysiNode;
|
} STableScanPhysiNode;
|
||||||
|
|
||||||
typedef STableScanPhysiNode STableSeqScanPhysiNode;
|
typedef STableScanPhysiNode STableSeqScanPhysiNode;
|
||||||
|
@ -257,17 +267,33 @@ typedef struct SIntervalPhysiNode {
|
||||||
SFillNode* pFill;
|
SFillNode* pFill;
|
||||||
} SIntervalPhysiNode;
|
} SIntervalPhysiNode;
|
||||||
|
|
||||||
|
typedef struct SMultiTableIntervalPhysiNode {
|
||||||
|
SIntervalPhysiNode interval;
|
||||||
|
SNodeList* pPartitionKeys;
|
||||||
|
} SMultiTableIntervalPhysiNode;
|
||||||
|
|
||||||
typedef struct SSessionWinodwPhysiNode {
|
typedef struct SSessionWinodwPhysiNode {
|
||||||
SWinodwPhysiNode window;
|
SWinodwPhysiNode window;
|
||||||
int64_t gap;
|
int64_t gap;
|
||||||
} SSessionWinodwPhysiNode;
|
} SSessionWinodwPhysiNode;
|
||||||
|
|
||||||
|
typedef struct SStateWinodwPhysiNode {
|
||||||
|
SWinodwPhysiNode window;
|
||||||
|
SNode* pStateKey;
|
||||||
|
} SStateWinodwPhysiNode;
|
||||||
|
|
||||||
typedef struct SSortPhysiNode {
|
typedef struct SSortPhysiNode {
|
||||||
SPhysiNode node;
|
SPhysiNode node;
|
||||||
SNodeList* pExprs; // these are expression list of order_by_clause and parameter expression of aggregate function
|
SNodeList* pExprs; // these are expression list of order_by_clause and parameter expression of aggregate function
|
||||||
SNodeList* pSortKeys; // element is SOrderByExprNode, and SOrderByExprNode::pExpr is SColumnNode
|
SNodeList* pSortKeys; // element is SOrderByExprNode, and SOrderByExprNode::pExpr is SColumnNode
|
||||||
} SSortPhysiNode;
|
} SSortPhysiNode;
|
||||||
|
|
||||||
|
typedef struct SPartitionPhysiNode {
|
||||||
|
SPhysiNode node;
|
||||||
|
SNodeList* pExprs; // these are expression list of partition_by_clause
|
||||||
|
SNodeList* pPartitionKeys;
|
||||||
|
} SPartitionPhysiNode;
|
||||||
|
|
||||||
typedef struct SDataSinkNode {
|
typedef struct SDataSinkNode {
|
||||||
ENodeType type;
|
ENodeType type;
|
||||||
SDataBlockDescNode* pInputDataBlockDesc;
|
SDataBlockDescNode* pInputDataBlockDesc;
|
||||||
|
@ -308,6 +334,7 @@ typedef enum EExplainMode {
|
||||||
typedef struct SExplainInfo {
|
typedef struct SExplainInfo {
|
||||||
EExplainMode mode;
|
EExplainMode mode;
|
||||||
bool verbose;
|
bool verbose;
|
||||||
|
double ratio;
|
||||||
} SExplainInfo;
|
} SExplainInfo;
|
||||||
|
|
||||||
typedef struct SQueryPlan {
|
typedef struct SQueryPlan {
|
||||||
|
|
|
@ -22,6 +22,7 @@ extern "C" {
|
||||||
|
|
||||||
#include "nodes.h"
|
#include "nodes.h"
|
||||||
#include "tmsg.h"
|
#include "tmsg.h"
|
||||||
|
#include "tvariant.h"
|
||||||
|
|
||||||
#define TABLE_TOTAL_COL_NUM(pMeta) ((pMeta)->tableInfo.numOfColumns + (pMeta)->tableInfo.numOfTags)
|
#define TABLE_TOTAL_COL_NUM(pMeta) ((pMeta)->tableInfo.numOfColumns + (pMeta)->tableInfo.numOfTags)
|
||||||
#define TABLE_META_SIZE(pMeta) (NULL == (pMeta) ? 0 : (sizeof(STableMeta) + TABLE_TOTAL_COL_NUM((pMeta)) * sizeof(SSchema)))
|
#define TABLE_META_SIZE(pMeta) (NULL == (pMeta) ? 0 : (sizeof(STableMeta) + TABLE_TOTAL_COL_NUM((pMeta)) * sizeof(SSchema)))
|
||||||
|
@ -79,6 +80,7 @@ typedef struct SValueNode {
|
||||||
char* literal;
|
char* literal;
|
||||||
bool isDuration;
|
bool isDuration;
|
||||||
bool translate;
|
bool translate;
|
||||||
|
bool genByCalc;
|
||||||
union {
|
union {
|
||||||
bool b;
|
bool b;
|
||||||
int64_t i;
|
int64_t i;
|
||||||
|
@ -187,7 +189,7 @@ typedef struct SLimitNode {
|
||||||
|
|
||||||
typedef struct SStateWindowNode {
|
typedef struct SStateWindowNode {
|
||||||
ENodeType type; // QUERY_NODE_STATE_WINDOW
|
ENodeType type; // QUERY_NODE_STATE_WINDOW
|
||||||
SNode* pCol;
|
SNode* pExpr;
|
||||||
} SStateWindowNode;
|
} SStateWindowNode;
|
||||||
|
|
||||||
typedef struct SSessionWindowNode {
|
typedef struct SSessionWindowNode {
|
||||||
|
@ -315,6 +317,8 @@ bool nodesIsTimelineQuery(const SNode* pQuery);
|
||||||
|
|
||||||
void* nodesGetValueFromNode(SValueNode *pNode);
|
void* nodesGetValueFromNode(SValueNode *pNode);
|
||||||
char* nodesGetStrValueFromNode(SValueNode *pNode);
|
char* nodesGetStrValueFromNode(SValueNode *pNode);
|
||||||
|
char *getFillModeString(EFillMode mode);
|
||||||
|
void valueNodeToVariant(const SValueNode* pNode, SVariant* pVal);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ extern int32_t filterInitFromNode(SNode *pNode, SFilterInfo **pinfo, uint32_t op
|
||||||
extern bool filterExecute(SFilterInfo *info, SSDataBlock *pSrc, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols);
|
extern bool filterExecute(SFilterInfo *info, SSDataBlock *pSrc, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols);
|
||||||
extern int32_t filterSetDataFromSlotId(SFilterInfo *info, void *param);
|
extern int32_t filterSetDataFromSlotId(SFilterInfo *info, void *param);
|
||||||
extern int32_t filterSetDataFromColId(SFilterInfo *info, void *param);
|
extern int32_t filterSetDataFromColId(SFilterInfo *info, void *param);
|
||||||
extern int32_t filterGetTimeRange(SFilterInfo *info, STimeWindow *win);
|
extern int32_t filterGetTimeRange(SNode *pNode, STimeWindow *win, bool *isStrict);
|
||||||
extern int32_t filterConverNcharColumns(SFilterInfo* pFilterInfo, int32_t rows, bool *gotNchar);
|
extern int32_t filterConverNcharColumns(SFilterInfo* pFilterInfo, int32_t rows, bool *gotNchar);
|
||||||
extern int32_t filterFreeNcharColumns(SFilterInfo* pFilterInfo);
|
extern int32_t filterFreeNcharColumns(SFilterInfo* pFilterInfo);
|
||||||
extern void filterFreeInfo(SFilterInfo *info);
|
extern void filterFreeInfo(SFilterInfo *info);
|
||||||
|
|
|
@ -71,7 +71,7 @@ int32_t schedulerInit(SSchedulerCfg *cfg);
|
||||||
* @param nodeList Qnode/Vnode address list, element is SQueryNodeAddr
|
* @param nodeList Qnode/Vnode address list, element is SQueryNodeAddr
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan* pDag, int64_t* pJob, const char* sql, SQueryResult *pRes);
|
int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryPlan *pDag, int64_t *pJob, const char *sql, int64_t startTs, SQueryResult *pRes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the query job, generated according to the query physical plan.
|
* Process the query job, generated according to the query physical plan.
|
||||||
|
|
|
@ -58,6 +58,9 @@ typedef struct {
|
||||||
void *pNode;
|
void *pNode;
|
||||||
} SNodeMsg;
|
} SNodeMsg;
|
||||||
|
|
||||||
|
typedef void (*RpcCfp)(void *parent, SRpcMsg *, SEpSet *);
|
||||||
|
typedef int (*RpcAfp)(void *parent, char *tableId, char *spi, char *encrypt, char *secret, char *ckey);
|
||||||
|
|
||||||
typedef struct SRpcInit {
|
typedef struct SRpcInit {
|
||||||
uint16_t localPort; // local port
|
uint16_t localPort; // local port
|
||||||
char * label; // for debug purpose
|
char * label; // for debug purpose
|
||||||
|
@ -74,10 +77,10 @@ typedef struct SRpcInit {
|
||||||
char *ckey; // ciphering key
|
char *ckey; // ciphering key
|
||||||
|
|
||||||
// call back to process incoming msg, code shall be ignored by server app
|
// call back to process incoming msg, code shall be ignored by server app
|
||||||
void (*cfp)(void *parent, SRpcMsg *, SEpSet *);
|
RpcCfp cfp;
|
||||||
|
|
||||||
// call back to retrieve the client auth info, for server app only
|
// call back to retrieve the client auth info, for server app only
|
||||||
int (*afp)(void *parent, char *tableId, char *spi, char *encrypt, char *secret, char *ckey);
|
RpcAfp afp;;
|
||||||
|
|
||||||
void *parent;
|
void *parent;
|
||||||
} SRpcInit;
|
} SRpcInit;
|
||||||
|
|
|
@ -483,6 +483,9 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME TAOS_DEF_ERROR_CODE(0, 0x2617)
|
#define TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME TAOS_DEF_ERROR_CODE(0, 0x2617)
|
||||||
#define TSDB_CODE_PAR_CORRESPONDING_STABLE_ERR TAOS_DEF_ERROR_CODE(0, 0x2618)
|
#define TSDB_CODE_PAR_CORRESPONDING_STABLE_ERR TAOS_DEF_ERROR_CODE(0, 0x2618)
|
||||||
|
|
||||||
|
//planner
|
||||||
|
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -480,9 +480,9 @@ enum {
|
||||||
SND_WORKER_TYPE__UNIQUE,
|
SND_WORKER_TYPE__UNIQUE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MND_VGID -1
|
#define MNODE_HANDLE -1
|
||||||
#define QND_VGID 1
|
#define QNODE_HANDLE 1
|
||||||
#define VND_VGID 0
|
#define DEFAULT_HANDLE 0
|
||||||
|
|
||||||
#define MAX_NUM_STR_SIZE 40
|
#define MAX_NUM_STR_SIZE 40
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ void taosWLockLatch(SRWLatch *pLatch);
|
||||||
void taosWUnLockLatch(SRWLatch *pLatch);
|
void taosWUnLockLatch(SRWLatch *pLatch);
|
||||||
void taosRLockLatch(SRWLatch *pLatch);
|
void taosRLockLatch(SRWLatch *pLatch);
|
||||||
void taosRUnLockLatch(SRWLatch *pLatch);
|
void taosRUnLockLatch(SRWLatch *pLatch);
|
||||||
|
int32_t taosWTryLockLatch(SRWLatch *pLatch);
|
||||||
|
|
||||||
// copy on read
|
// copy on read
|
||||||
#define taosCorBeginRead(x) \
|
#define taosCorBeginRead(x) \
|
||||||
|
|
|
@ -24,11 +24,10 @@ extern "C" {
|
||||||
|
|
||||||
typedef enum { PROC_QUEUE, PROC_REQ, PROC_RSP, PROC_REGIST, PROC_RELEASE } ProcFuncType;
|
typedef enum { PROC_QUEUE, PROC_REQ, PROC_RSP, PROC_REGIST, PROC_RELEASE } ProcFuncType;
|
||||||
|
|
||||||
typedef struct SProcQueue SProcQueue;
|
typedef struct SProcObj SProcObj;
|
||||||
typedef struct SProcObj SProcObj;
|
|
||||||
typedef void *(*ProcMallocFp)(int32_t contLen);
|
typedef void *(*ProcMallocFp)(int32_t contLen);
|
||||||
typedef void *(*ProcFreeFp)(void *pCont);
|
typedef void *(*ProcFreeFp)(void *pCont);
|
||||||
typedef void *(*ProcConsumeFp)(void *pParent, void *pHead, int16_t headLen, void *pBody, int32_t bodyLen,
|
typedef void *(*ProcConsumeFp)(void *parent, void *pHead, int16_t headLen, void *pBody, int32_t bodyLen,
|
||||||
ProcFuncType ftype);
|
ProcFuncType ftype);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -43,7 +42,7 @@ typedef struct {
|
||||||
ProcMallocFp parentMallocBodyFp;
|
ProcMallocFp parentMallocBodyFp;
|
||||||
ProcFreeFp parentFreeBodyFp;
|
ProcFreeFp parentFreeBodyFp;
|
||||||
SShm shm;
|
SShm shm;
|
||||||
void *pParent;
|
void *parent;
|
||||||
const char *name;
|
const char *name;
|
||||||
bool isChild;
|
bool isChild;
|
||||||
} SProcCfg;
|
} SProcCfg;
|
||||||
|
@ -51,10 +50,13 @@ typedef struct {
|
||||||
SProcObj *taosProcInit(const SProcCfg *pCfg);
|
SProcObj *taosProcInit(const SProcCfg *pCfg);
|
||||||
void taosProcCleanup(SProcObj *pProc);
|
void taosProcCleanup(SProcObj *pProc);
|
||||||
int32_t taosProcRun(SProcObj *pProc);
|
int32_t taosProcRun(SProcObj *pProc);
|
||||||
int32_t taosProcPutToChildQ(SProcObj *pProc, const void *pHead, int16_t headLen, const void *pBody, int32_t bodyLen,
|
|
||||||
ProcFuncType ftype);
|
int32_t taosProcPutToChildQ(SProcObj *pProc, const void *pHead, int16_t headLen, const void *pBody, int32_t bodyLen,
|
||||||
void taosProcPutToParentQ(SProcObj *pProc, const void *pHead, int16_t headLen, const void *pBody, int32_t bodyLen,
|
void *handle, ProcFuncType ftype);
|
||||||
ProcFuncType ftype);
|
void taosProcRemoveHandle(SProcObj *pProc, void *handle);
|
||||||
|
void taosProcCloseHandles(SProcObj *pProc, void (*HandleFp)(void *handle));
|
||||||
|
void taosProcPutToParentQ(SProcObj *pProc, const void *pHead, int16_t headLen, const void *pBody, int32_t bodyLen,
|
||||||
|
ProcFuncType ftype);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,6 +163,7 @@ typedef struct SReqResultInfo {
|
||||||
uint64_t totalRows;
|
uint64_t totalRows;
|
||||||
uint32_t current;
|
uint32_t current;
|
||||||
bool completed;
|
bool completed;
|
||||||
|
int32_t precision;
|
||||||
int32_t payloadLen;
|
int32_t payloadLen;
|
||||||
} SReqResultInfo;
|
} SReqResultInfo;
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,7 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList
|
||||||
void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter;
|
void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter;
|
||||||
|
|
||||||
SQueryResult res = {.code = 0, .numOfRows = 0, .msgSize = ERROR_MSG_BUF_DEFAULT_SIZE, .msg = pRequest->msgBuf};
|
SQueryResult res = {.code = 0, .numOfRows = 0, .msgSize = ERROR_MSG_BUF_DEFAULT_SIZE, .msg = pRequest->msgBuf};
|
||||||
int32_t code = schedulerExecJob(pTransporter, pNodeList, pDag, &pRequest->body.queryJob, pRequest->sqlstr, &res);
|
int32_t code = schedulerExecJob(pTransporter, pNodeList, pDag, &pRequest->body.queryJob, pRequest->sqlstr, pRequest->metric.start, &res);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
if (pRequest->body.queryJob != 0) {
|
if (pRequest->body.queryJob != 0) {
|
||||||
schedulerFreeJob(pRequest->body.queryJob);
|
schedulerFreeJob(pRequest->body.queryJob);
|
||||||
|
@ -825,6 +825,7 @@ int32_t setQueryResultFromRsp(SReqResultInfo* pResultInfo, const SRetrieveTableR
|
||||||
pResultInfo->current = 0;
|
pResultInfo->current = 0;
|
||||||
pResultInfo->completed = (pRsp->completed == 1);
|
pResultInfo->completed = (pRsp->completed == 1);
|
||||||
pResultInfo->payloadLen = htonl(pRsp->compLen);
|
pResultInfo->payloadLen = htonl(pRsp->compLen);
|
||||||
|
pResultInfo->precision = pRsp->precision;
|
||||||
|
|
||||||
// TODO handle the compressed case
|
// TODO handle the compressed case
|
||||||
pResultInfo->totalRows += pResultInfo->numOfRows;
|
pResultInfo->totalRows += pResultInfo->numOfRows;
|
||||||
|
|
|
@ -264,8 +264,17 @@ int *taos_fetch_lengths(TAOS_RES *res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TAOS_ROW *taos_result_block(TAOS_RES *res) {
|
TAOS_ROW *taos_result_block(TAOS_RES *res) {
|
||||||
// TODO
|
SRequestObj* pRequest = (SRequestObj*) res;
|
||||||
return NULL;
|
if (pRequest == NULL) {
|
||||||
|
terrno = TSDB_CODE_INVALID_PARA;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taos_is_update_query(res)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pRequest->body.resInfo.row;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo intergrate with tDataTypes
|
// todo intergrate with tDataTypes
|
||||||
|
@ -313,7 +322,14 @@ int taos_affected_rows(TAOS_RES *res) {
|
||||||
return pResInfo->numOfRows;
|
return pResInfo->numOfRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
int taos_result_precision(TAOS_RES *res) { return TSDB_TIME_PRECISION_MILLI; }
|
int taos_result_precision(TAOS_RES *res) {
|
||||||
|
SRequestObj* pRequest = (SRequestObj*) res;
|
||||||
|
if (pRequest == NULL) {
|
||||||
|
return TSDB_TIME_PRECISION_MILLI;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pRequest->body.resInfo.precision;
|
||||||
|
}
|
||||||
|
|
||||||
int taos_select_db(TAOS *taos, const char *db) {
|
int taos_select_db(TAOS *taos, const char *db) {
|
||||||
STscObj *pObj = (STscObj *)taos;
|
STscObj *pObj = (STscObj *)taos;
|
||||||
|
|
|
@ -79,6 +79,7 @@ struct tmq_t {
|
||||||
tmq_commit_cb* commit_cb;
|
tmq_commit_cb* commit_cb;
|
||||||
int32_t nextTopicIdx;
|
int32_t nextTopicIdx;
|
||||||
int8_t epStatus;
|
int8_t epStatus;
|
||||||
|
int32_t epSkipCnt;
|
||||||
int32_t waitingRequest;
|
int32_t waitingRequest;
|
||||||
int32_t readyRequest;
|
int32_t readyRequest;
|
||||||
SArray* clientTopics; // SArray<SMqClientTopic>
|
SArray* clientTopics; // SArray<SMqClientTopic>
|
||||||
|
@ -107,6 +108,7 @@ typedef struct {
|
||||||
// connection info
|
// connection info
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
int32_t vgStatus;
|
int32_t vgStatus;
|
||||||
|
int64_t skipCnt;
|
||||||
SEpSet epSet;
|
SEpSet epSet;
|
||||||
} SMqClientVg;
|
} SMqClientVg;
|
||||||
|
|
||||||
|
@ -138,6 +140,7 @@ typedef struct {
|
||||||
tmq_t* tmq;
|
tmq_t* tmq;
|
||||||
SMqClientVg* pVg;
|
SMqClientVg* pVg;
|
||||||
int32_t epoch;
|
int32_t epoch;
|
||||||
|
int32_t vgId;
|
||||||
tsem_t rspSem;
|
tsem_t rspSem;
|
||||||
tmq_message_t** msg;
|
tmq_message_t** msg;
|
||||||
int32_t sync;
|
int32_t sync;
|
||||||
|
@ -313,6 +316,7 @@ tmq_t* tmq_consumer_new(void* conn, tmq_conf_t* conf, char* errstr, int32_t errs
|
||||||
pTmq->waitingRequest = 0;
|
pTmq->waitingRequest = 0;
|
||||||
pTmq->readyRequest = 0;
|
pTmq->readyRequest = 0;
|
||||||
pTmq->epStatus = 0;
|
pTmq->epStatus = 0;
|
||||||
|
pTmq->epSkipCnt = 0;
|
||||||
// set conf
|
// set conf
|
||||||
strcpy(pTmq->clientId, conf->clientId);
|
strcpy(pTmq->clientId, conf->clientId);
|
||||||
strcpy(pTmq->groupId, conf->groupId);
|
strcpy(pTmq->groupId, conf->groupId);
|
||||||
|
@ -348,6 +352,8 @@ tmq_t* tmq_consumer_new1(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
||||||
pTmq->epoch = 0;
|
pTmq->epoch = 0;
|
||||||
pTmq->waitingRequest = 0;
|
pTmq->waitingRequest = 0;
|
||||||
pTmq->readyRequest = 0;
|
pTmq->readyRequest = 0;
|
||||||
|
pTmq->epStatus = 0;
|
||||||
|
pTmq->epSkipCnt = 0;
|
||||||
// set conf
|
// set conf
|
||||||
strcpy(pTmq->clientId, conf->clientId);
|
strcpy(pTmq->clientId, conf->clientId);
|
||||||
strcpy(pTmq->groupId, conf->groupId);
|
strcpy(pTmq->groupId, conf->groupId);
|
||||||
|
@ -834,7 +840,7 @@ int32_t tmqPollCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||||
SMqClientVg* pVg = pParam->pVg;
|
SMqClientVg* pVg = pParam->pVg;
|
||||||
tmq_t* tmq = pParam->tmq;
|
tmq_t* tmq = pParam->tmq;
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
tscWarn("msg discard, code:%x", code);
|
tscWarn("msg discard from vg %d, epoch %d, code:%x", pParam->vgId, pParam->epoch, code);
|
||||||
goto CREATE_MSG_FAIL;
|
goto CREATE_MSG_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,13 +848,13 @@ int32_t tmqPollCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||||
int32_t tmqEpoch = atomic_load_32(&tmq->epoch);
|
int32_t tmqEpoch = atomic_load_32(&tmq->epoch);
|
||||||
if (msgEpoch < tmqEpoch) {
|
if (msgEpoch < tmqEpoch) {
|
||||||
/*printf("discard rsp epoch %d, current epoch %d\n", msgEpoch, tmqEpoch);*/
|
/*printf("discard rsp epoch %d, current epoch %d\n", msgEpoch, tmqEpoch);*/
|
||||||
tsem_post(&tmq->rspSem);
|
/*tsem_post(&tmq->rspSem);*/
|
||||||
tscWarn("discard rsp epoch %d, current epoch %d", msgEpoch, tmqEpoch);
|
tscWarn("discard rsp from vg %d, epoch %d, current epoch %d", pParam->vgId, msgEpoch, tmqEpoch);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msgEpoch != tmqEpoch) {
|
if (msgEpoch != tmqEpoch) {
|
||||||
tscWarn("mismatch rsp epoch %d, current epoch %d", msgEpoch, tmqEpoch);
|
tscWarn("mismatch rsp from vg %d, epoch %d, current epoch %d", pParam->vgId, msgEpoch, tmqEpoch);
|
||||||
} else {
|
} else {
|
||||||
atomic_sub_fetch_32(&tmq->waitingRequest, 1);
|
atomic_sub_fetch_32(&tmq->waitingRequest, 1);
|
||||||
}
|
}
|
||||||
|
@ -892,29 +898,29 @@ int32_t tmqPollCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tscError("tmq recv poll: vg %d, req offset %ld, rsp offset %ld", pParam->pVg->vgId, pRsp->msg.reqOffset,
|
tscDebug("consumer %ld recv poll: vg %d, req offset %ld, rsp offset %ld", tmq->consumerId, pParam->pVg->vgId, pRsp->msg.reqOffset,
|
||||||
pRsp->msg.rspOffset);
|
pRsp->msg.rspOffset);
|
||||||
|
|
||||||
pRsp->vg = pParam->pVg;
|
pRsp->vg = pParam->pVg;
|
||||||
taosWriteQitem(tmq->mqueue, pRsp);
|
taosWriteQitem(tmq->mqueue, pRsp);
|
||||||
atomic_add_fetch_32(&tmq->readyRequest, 1);
|
atomic_add_fetch_32(&tmq->readyRequest, 1);
|
||||||
tsem_post(&tmq->rspSem);
|
/*tsem_post(&tmq->rspSem);*/
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
CREATE_MSG_FAIL:
|
CREATE_MSG_FAIL:
|
||||||
if (pParam->epoch == tmq->epoch) {
|
if (pParam->epoch == tmq->epoch) {
|
||||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||||
}
|
}
|
||||||
tsem_post(&tmq->rspSem);
|
/*tsem_post(&tmq->rspSem);*/
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tmqUpdateEp(tmq_t* tmq, int32_t epoch, SMqCMGetSubEpRsp* pRsp) {
|
bool tmqUpdateEp(tmq_t* tmq, int32_t epoch, SMqCMGetSubEpRsp* pRsp) {
|
||||||
/*printf("call update ep %d\n", epoch);*/
|
/*printf("call update ep %d\n", epoch);*/
|
||||||
tscDebug("tmq update ep epoch %d to epoch %d", tmq->epoch, epoch);
|
|
||||||
bool set = false;
|
bool set = false;
|
||||||
int32_t topicNumGet = taosArrayGetSize(pRsp->topics);
|
int32_t topicNumGet = taosArrayGetSize(pRsp->topics);
|
||||||
char vgKey[TSDB_TOPIC_FNAME_LEN + 22];
|
char vgKey[TSDB_TOPIC_FNAME_LEN + 22];
|
||||||
|
tscDebug("consumer %ld update ep epoch %d to epoch %d, topic num: %d", tmq->consumerId, tmq->epoch, epoch, topicNumGet);
|
||||||
SArray* newTopics = taosArrayInit(topicNumGet, sizeof(SMqClientTopic));
|
SArray* newTopics = taosArrayInit(topicNumGet, sizeof(SMqClientTopic));
|
||||||
if (newTopics == NULL) {
|
if (newTopics == NULL) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -932,17 +938,19 @@ bool tmqUpdateEp(tmq_t* tmq, int32_t epoch, SMqCMGetSubEpRsp* pRsp) {
|
||||||
taosHashClear(pHash);
|
taosHashClear(pHash);
|
||||||
topic.topicName = strdup(pTopicEp->topic);
|
topic.topicName = strdup(pTopicEp->topic);
|
||||||
|
|
||||||
|
tscDebug("consumer %ld update topic: %s", tmq->consumerId, topic.topicName);
|
||||||
int32_t topicNumCur = taosArrayGetSize(tmq->clientTopics);
|
int32_t topicNumCur = taosArrayGetSize(tmq->clientTopics);
|
||||||
for (int32_t j = 0; j < topicNumCur; j++) {
|
for (int32_t j = 0; j < topicNumCur; j++) {
|
||||||
// find old topic
|
// find old topic
|
||||||
SMqClientTopic* pTopicCur = taosArrayGet(tmq->clientTopics, j);
|
SMqClientTopic* pTopicCur = taosArrayGet(tmq->clientTopics, j);
|
||||||
if (pTopicCur->vgs && strcmp(pTopicCur->topicName, pTopicEp->topic) == 0) {
|
if (pTopicCur->vgs && strcmp(pTopicCur->topicName, pTopicEp->topic) == 0) {
|
||||||
int32_t vgNumCur = taosArrayGetSize(pTopicCur->vgs);
|
int32_t vgNumCur = taosArrayGetSize(pTopicCur->vgs);
|
||||||
|
tscDebug("consumer %ld new vg num: %d", tmq->consumerId, vgNumCur);
|
||||||
if (vgNumCur == 0) break;
|
if (vgNumCur == 0) break;
|
||||||
for (int32_t k = 0; k < vgNumCur; k++) {
|
for (int32_t k = 0; k < vgNumCur; k++) {
|
||||||
SMqClientVg* pVgCur = taosArrayGet(pTopicCur->vgs, k);
|
SMqClientVg* pVgCur = taosArrayGet(pTopicCur->vgs, k);
|
||||||
sprintf(vgKey, "%s:%d", topic.topicName, pVgCur->vgId);
|
sprintf(vgKey, "%s:%d", topic.topicName, pVgCur->vgId);
|
||||||
tscDebug("epoch %d vg %d build %s\n", epoch, pVgCur->vgId, vgKey);
|
tscDebug("consumer %ld epoch %d vg %d build %s", tmq->consumerId, epoch, pVgCur->vgId, vgKey);
|
||||||
taosHashPut(pHash, vgKey, strlen(vgKey), &pVgCur->currentOffset, sizeof(int64_t));
|
taosHashPut(pHash, vgKey, strlen(vgKey), &pVgCur->currentOffset, sizeof(int64_t));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -956,18 +964,19 @@ bool tmqUpdateEp(tmq_t* tmq, int32_t epoch, SMqCMGetSubEpRsp* pRsp) {
|
||||||
sprintf(vgKey, "%s:%d", topic.topicName, pVgEp->vgId);
|
sprintf(vgKey, "%s:%d", topic.topicName, pVgEp->vgId);
|
||||||
int64_t* pOffset = taosHashGet(pHash, vgKey, strlen(vgKey));
|
int64_t* pOffset = taosHashGet(pHash, vgKey, strlen(vgKey));
|
||||||
int64_t offset = pVgEp->offset;
|
int64_t offset = pVgEp->offset;
|
||||||
tscDebug("epoch %d vg %d offset og to %ld\n", epoch, pVgEp->vgId, offset);
|
tscDebug("consumer %ld epoch %d vg %d offset og to %ld", tmq->consumerId, epoch, pVgEp->vgId, offset);
|
||||||
if (pOffset != NULL) {
|
if (pOffset != NULL) {
|
||||||
offset = *pOffset;
|
offset = *pOffset;
|
||||||
tscDebug("epoch %d vg %d found %s\n", epoch, pVgEp->vgId, vgKey);
|
tscDebug("consumer %ld epoch %d vg %d found %s", tmq->consumerId, epoch, pVgEp->vgId, vgKey);
|
||||||
}
|
}
|
||||||
tscDebug("epoch %d vg %d offset set to %ld\n", epoch, pVgEp->vgId, offset);
|
tscDebug("consumer %ld epoch %d vg %d offset set to %ld\n", tmq->consumerId, epoch, pVgEp->vgId, offset);
|
||||||
SMqClientVg clientVg = {
|
SMqClientVg clientVg = {
|
||||||
.pollCnt = 0,
|
.pollCnt = 0,
|
||||||
.currentOffset = offset,
|
.currentOffset = offset,
|
||||||
.vgId = pVgEp->vgId,
|
.vgId = pVgEp->vgId,
|
||||||
.epSet = pVgEp->epSet,
|
.epSet = pVgEp->epSet,
|
||||||
.vgStatus = TMQ_VG_STATUS__IDLE,
|
.vgStatus = TMQ_VG_STATUS__IDLE,
|
||||||
|
.skipCnt = 0,
|
||||||
};
|
};
|
||||||
taosArrayPush(topic.vgs, &clientVg);
|
taosArrayPush(topic.vgs, &clientVg);
|
||||||
set = true;
|
set = true;
|
||||||
|
@ -984,9 +993,8 @@ bool tmqUpdateEp(tmq_t* tmq, int32_t epoch, SMqCMGetSubEpRsp* pRsp) {
|
||||||
int32_t tmqAskEpCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
int32_t tmqAskEpCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||||
SMqAskEpCbParam* pParam = (SMqAskEpCbParam*)param;
|
SMqAskEpCbParam* pParam = (SMqAskEpCbParam*)param;
|
||||||
tmq_t* tmq = pParam->tmq;
|
tmq_t* tmq = pParam->tmq;
|
||||||
tscDebug("consumer %ld recv ep", tmq->consumerId);
|
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
tscError("get topic endpoint error, not ready, wait:%d\n", pParam->sync);
|
tscError("consumer %ld get topic endpoint error, not ready, wait:%d", tmq->consumerId, pParam->sync);
|
||||||
goto END;
|
goto END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -995,6 +1003,7 @@ int32_t tmqAskEpCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||||
// Epoch will only increase when received newer epoch ep msg
|
// Epoch will only increase when received newer epoch ep msg
|
||||||
SMqRspHead* head = pMsg->pData;
|
SMqRspHead* head = pMsg->pData;
|
||||||
int32_t epoch = atomic_load_32(&tmq->epoch);
|
int32_t epoch = atomic_load_32(&tmq->epoch);
|
||||||
|
tscDebug("consumer %ld recv ep, msg epoch %d, current epoch %d", tmq->consumerId, head->epoch, epoch);
|
||||||
if (head->epoch <= epoch) {
|
if (head->epoch <= epoch) {
|
||||||
goto END;
|
goto END;
|
||||||
}
|
}
|
||||||
|
@ -1019,7 +1028,7 @@ int32_t tmqAskEpCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||||
tDecodeSMqCMGetSubEpRsp(POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pRsp);
|
tDecodeSMqCMGetSubEpRsp(POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pRsp);
|
||||||
|
|
||||||
taosWriteQitem(tmq->mqueue, pRsp);
|
taosWriteQitem(tmq->mqueue, pRsp);
|
||||||
tsem_post(&tmq->rspSem);
|
/*tsem_post(&tmq->rspSem);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
END:
|
END:
|
||||||
|
@ -1033,9 +1042,11 @@ END:
|
||||||
int32_t tmqAskEp(tmq_t* tmq, bool sync) {
|
int32_t tmqAskEp(tmq_t* tmq, bool sync) {
|
||||||
int8_t epStatus = atomic_val_compare_exchange_8(&tmq->epStatus, 0, 1);
|
int8_t epStatus = atomic_val_compare_exchange_8(&tmq->epStatus, 0, 1);
|
||||||
if (epStatus == 1) {
|
if (epStatus == 1) {
|
||||||
tscDebug("consumer %ld skip ask ep", tmq->consumerId);
|
int32_t epSkipCnt = atomic_add_fetch_32(&tmq->epSkipCnt, 1);
|
||||||
return 0;
|
tscDebug("consumer %ld skip ask ep cnt %d", tmq->consumerId, epSkipCnt);
|
||||||
|
if (epSkipCnt < 5000) return 0;
|
||||||
}
|
}
|
||||||
|
atomic_store_32(&tmq->epSkipCnt, 0);
|
||||||
int32_t tlen = sizeof(SMqCMGetSubEpReq);
|
int32_t tlen = sizeof(SMqCMGetSubEpReq);
|
||||||
SMqCMGetSubEpReq* req = taosMemoryMalloc(tlen);
|
SMqCMGetSubEpReq* req = taosMemoryMalloc(tlen);
|
||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
|
@ -1221,24 +1232,34 @@ int32_t tmqPollImpl(tmq_t* tmq, int64_t blockingTime) {
|
||||||
SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j);
|
SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j);
|
||||||
int32_t vgStatus = atomic_val_compare_exchange_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE, TMQ_VG_STATUS__WAIT);
|
int32_t vgStatus = atomic_val_compare_exchange_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE, TMQ_VG_STATUS__WAIT);
|
||||||
if (vgStatus != TMQ_VG_STATUS__IDLE) {
|
if (vgStatus != TMQ_VG_STATUS__IDLE) {
|
||||||
tscDebug("consumer %ld skip vg %d", tmq->consumerId, pVg->vgId);
|
int64_t skipCnt = atomic_add_fetch_64(&pVg->skipCnt, 1);
|
||||||
|
tscDebug("consumer %ld epoch %d skip vg %d skip cnt %ld", tmq->consumerId, tmq->epoch, pVg->vgId, skipCnt);
|
||||||
continue;
|
continue;
|
||||||
|
#if 0
|
||||||
|
if (skipCnt < 30000) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
tscDebug("consumer %ld skip vg %d skip too much reset", tmq->consumerId, pVg->vgId);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
atomic_store_64(&pVg->skipCnt, 0);
|
||||||
SMqPollReq* pReq = tmqBuildConsumeReqImpl(tmq, blockingTime, pTopic, pVg);
|
SMqPollReq* pReq = tmqBuildConsumeReqImpl(tmq, blockingTime, pTopic, pVg);
|
||||||
if (pReq == NULL) {
|
if (pReq == NULL) {
|
||||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||||
tsem_post(&tmq->rspSem);
|
/*tsem_post(&tmq->rspSem);*/
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SMqPollCbParam* pParam = taosMemoryMalloc(sizeof(SMqPollCbParam));
|
SMqPollCbParam* pParam = taosMemoryMalloc(sizeof(SMqPollCbParam));
|
||||||
if (pParam == NULL) {
|
if (pParam == NULL) {
|
||||||
taosMemoryFree(pReq);
|
taosMemoryFree(pReq);
|
||||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||||
tsem_post(&tmq->rspSem);
|
/*tsem_post(&tmq->rspSem);*/
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pParam->tmq = tmq;
|
pParam->tmq = tmq;
|
||||||
pParam->pVg = pVg;
|
pParam->pVg = pVg;
|
||||||
|
pParam->vgId = pVg->vgId;
|
||||||
pParam->epoch = tmq->epoch;
|
pParam->epoch = tmq->epoch;
|
||||||
pParam->sync = 0;
|
pParam->sync = 0;
|
||||||
|
|
||||||
|
@ -1247,7 +1268,7 @@ int32_t tmqPollImpl(tmq_t* tmq, int64_t blockingTime) {
|
||||||
taosMemoryFree(pReq);
|
taosMemoryFree(pReq);
|
||||||
taosMemoryFree(pParam);
|
taosMemoryFree(pParam);
|
||||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||||
tsem_post(&tmq->rspSem);
|
/*tsem_post(&tmq->rspSem);*/
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1265,7 +1286,7 @@ int32_t tmqPollImpl(tmq_t* tmq, int64_t blockingTime) {
|
||||||
int64_t transporterId = 0;
|
int64_t transporterId = 0;
|
||||||
/*printf("send poll\n");*/
|
/*printf("send poll\n");*/
|
||||||
atomic_add_fetch_32(&tmq->waitingRequest, 1);
|
atomic_add_fetch_32(&tmq->waitingRequest, 1);
|
||||||
tscDebug("consumer %ld send poll: vg %d, req offset %ld", tmq->consumerId, pVg->vgId, pVg->currentOffset);
|
tscDebug("consumer %ld send poll: vg %d, epoch %d, req offset %ld", tmq->consumerId, pVg->vgId, tmq->epoch, pVg->currentOffset);
|
||||||
/*printf("send vg %d %ld\n", pVg->vgId, pVg->currentOffset);*/
|
/*printf("send vg %d %ld\n", pVg->vgId, pVg->currentOffset);*/
|
||||||
asyncSendMsgToServer(tmq->pTscObj->pAppInfo->pTransporter, &pVg->epSet, &transporterId, sendInfo);
|
asyncSendMsgToServer(tmq->pTscObj->pAppInfo->pTransporter, &pVg->epSet, &transporterId, sendInfo);
|
||||||
pVg->pollCnt++;
|
pVg->pollCnt++;
|
||||||
|
@ -1379,7 +1400,7 @@ tmq_message_t* tmq_consumer_poll(tmq_t* tmq, int64_t blocking_time) {
|
||||||
tmqAskEp(tmq, false);
|
tmqAskEp(tmq, false);
|
||||||
tmqPollImpl(tmq, blocking_time);
|
tmqPollImpl(tmq, blocking_time);
|
||||||
|
|
||||||
tsem_wait(&tmq->rspSem);
|
/*tsem_wait(&tmq->rspSem);*/
|
||||||
|
|
||||||
rspMsg = tmqHandleAllRsp(tmq, blocking_time, false);
|
rspMsg = tmqHandleAllRsp(tmq, blocking_time, false);
|
||||||
if (rspMsg) {
|
if (rspMsg) {
|
||||||
|
|
|
@ -400,6 +400,7 @@ TEST(testCase, show_vgroup_Test) {
|
||||||
taos_free_result(pRes);
|
taos_free_result(pRes);
|
||||||
taos_close(pConn);
|
taos_close(pConn);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST(testCase, create_multiple_tables) {
|
TEST(testCase, create_multiple_tables) {
|
||||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||||
|
@ -458,7 +459,7 @@ TEST(testCase, create_multiple_tables) {
|
||||||
|
|
||||||
taos_free_result(pRes);
|
taos_free_result(pRes);
|
||||||
|
|
||||||
for (int32_t i = 0; i < 20; ++i) {
|
for (int32_t i = 0; i < 25000; ++i) {
|
||||||
char sql[512] = {0};
|
char sql[512] = {0};
|
||||||
snprintf(sql, tListLen(sql),
|
snprintf(sql, tListLen(sql),
|
||||||
"create table t_x_%d using st1 tags(2) t_x_%d using st1 tags(5) t_x_%d using st1 tags(911)", i,
|
"create table t_x_%d using st1 tags(2) t_x_%d using st1 tags(5) t_x_%d using st1 tags(911)", i,
|
||||||
|
@ -652,7 +653,6 @@ TEST(testCase, projection_query_stables) {
|
||||||
taos_free_result(pRes);
|
taos_free_result(pRes);
|
||||||
taos_close(pConn);
|
taos_close(pConn);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
TEST(testCase, agg_query_tables) {
|
TEST(testCase, agg_query_tables) {
|
||||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||||
|
|
|
@ -33,7 +33,8 @@ int tdAllocMemForCol(SDataCol *pCol, int maxPoints) {
|
||||||
spaceNeeded += (int)nBitmapBytes;
|
spaceNeeded += (int)nBitmapBytes;
|
||||||
// TODO: Currently, the compression of bitmap parts is affiliated to the column data parts, thus allocate 1 more
|
// TODO: Currently, the compression of bitmap parts is affiliated to the column data parts, thus allocate 1 more
|
||||||
// TYPE_BYTES as to comprise complete TYPE_BYTES. Otherwise, invalid read/write would be triggered.
|
// TYPE_BYTES as to comprise complete TYPE_BYTES. Otherwise, invalid read/write would be triggered.
|
||||||
spaceNeeded += TYPE_BYTES[pCol->type];
|
// spaceNeeded += TYPE_BYTES[pCol->type]; // the bitmap part is append as a single part since 2022.04.03, thus remove
|
||||||
|
// the additional space
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pCol->spaceSize < spaceNeeded) {
|
if (pCol->spaceSize < spaceNeeded) {
|
||||||
|
@ -47,6 +48,7 @@ int tdAllocMemForCol(SDataCol *pCol, int maxPoints) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef TD_SUPPORT_BITMAP
|
#ifdef TD_SUPPORT_BITMAP
|
||||||
|
|
||||||
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||||
pCol->pBitmap = POINTER_SHIFT(pCol->pData, pCol->bytes * maxPoints);
|
pCol->pBitmap = POINTER_SHIFT(pCol->pData, pCol->bytes * maxPoints);
|
||||||
pCol->dataOff = POINTER_SHIFT(pCol->pBitmap, nBitmapBytes);
|
pCol->dataOff = POINTER_SHIFT(pCol->pBitmap, nBitmapBytes);
|
||||||
|
@ -306,7 +308,7 @@ static FORCE_INLINE const void *tdGetColDataOfRowUnsafe(SDataCol *pCol, int row)
|
||||||
|
|
||||||
bool isNEleNull(SDataCol *pCol, int nEle) {
|
bool isNEleNull(SDataCol *pCol, int nEle) {
|
||||||
if (isAllRowsNull(pCol)) return true;
|
if (isAllRowsNull(pCol)) return true;
|
||||||
for (int i = 0; i < nEle; i++) {
|
for (int i = 0; i < nEle; ++i) {
|
||||||
if (!isNull(tdGetColDataOfRowUnsafe(pCol, i), pCol->type)) return false;
|
if (!isNull(tdGetColDataOfRowUnsafe(pCol, i), pCol->type)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -327,7 +329,7 @@ static FORCE_INLINE void dataColSetNullAt(SDataCol *pCol, int index) {
|
||||||
static void dataColSetNEleNull(SDataCol *pCol, int nEle) {
|
static void dataColSetNEleNull(SDataCol *pCol, int nEle) {
|
||||||
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||||
pCol->len = 0;
|
pCol->len = 0;
|
||||||
for (int i = 0; i < nEle; i++) {
|
for (int i = 0; i < nEle; ++i) {
|
||||||
dataColSetNullAt(pCol, i);
|
dataColSetNullAt(pCol, i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -343,7 +345,7 @@ void *dataColSetOffset(SDataCol *pCol, int nEle) {
|
||||||
// char *tptr = (char *)(pCol->pData);
|
// char *tptr = (char *)(pCol->pData);
|
||||||
|
|
||||||
VarDataOffsetT offset = 0;
|
VarDataOffsetT offset = 0;
|
||||||
for (int i = 0; i < nEle; i++) {
|
for (int i = 0; i < nEle; ++i) {
|
||||||
pCol->dataOff[i] = offset;
|
pCol->dataOff[i] = offset;
|
||||||
offset += varDataTLen(tptr);
|
offset += varDataTLen(tptr);
|
||||||
tptr = POINTER_SHIFT(tptr, varDataTLen(tptr));
|
tptr = POINTER_SHIFT(tptr, varDataTLen(tptr));
|
||||||
|
@ -371,6 +373,7 @@ SDataCols *tdNewDataCols(int maxCols, int maxRows) {
|
||||||
tdFreeDataCols(pCols);
|
tdFreeDataCols(pCols);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#if 0 // no need as calloc used
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < maxCols; i++) {
|
for (i = 0; i < maxCols; i++) {
|
||||||
pCols->cols[i].spaceSize = 0;
|
pCols->cols[i].spaceSize = 0;
|
||||||
|
@ -378,6 +381,7 @@ SDataCols *tdNewDataCols(int maxCols, int maxRows) {
|
||||||
pCols->cols[i].pData = NULL;
|
pCols->cols[i].pData = NULL;
|
||||||
pCols->cols[i].dataOff = NULL;
|
pCols->cols[i].dataOff = NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return pCols;
|
return pCols;
|
||||||
|
@ -391,17 +395,21 @@ int tdInitDataCols(SDataCols *pCols, STSchema *pSchema) {
|
||||||
void *ptr = (SDataCol *)taosMemoryRealloc(pCols->cols, sizeof(SDataCol) * pCols->maxCols);
|
void *ptr = (SDataCol *)taosMemoryRealloc(pCols->cols, sizeof(SDataCol) * pCols->maxCols);
|
||||||
if (ptr == NULL) return -1;
|
if (ptr == NULL) return -1;
|
||||||
pCols->cols = ptr;
|
pCols->cols = ptr;
|
||||||
for (i = oldMaxCols; i < pCols->maxCols; i++) {
|
for (i = oldMaxCols; i < pCols->maxCols; ++i) {
|
||||||
pCols->cols[i].pData = NULL;
|
pCols->cols[i].pData = NULL;
|
||||||
pCols->cols[i].dataOff = NULL;
|
pCols->cols[i].dataOff = NULL;
|
||||||
|
pCols->cols[i].pBitmap = NULL;
|
||||||
pCols->cols[i].spaceSize = 0;
|
pCols->cols[i].spaceSize = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
tdResetDataCols(pCols); // redundant loop to reset len/blen to 0, already reset in following dataColInit(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
tdResetDataCols(pCols);
|
pCols->numOfRows = 0;
|
||||||
pCols->numOfCols = schemaNCols(pSchema);
|
pCols->numOfCols = schemaNCols(pSchema);
|
||||||
|
|
||||||
for (i = 0; i < schemaNCols(pSchema); i++) {
|
for (i = 0; i < schemaNCols(pSchema); ++i) {
|
||||||
dataColInit(pCols->cols + i, schemaColAt(pSchema, i), pCols->maxPoints);
|
dataColInit(pCols->cols + i, schemaColAt(pSchema, i), pCols->maxPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,7 +421,7 @@ SDataCols *tdFreeDataCols(SDataCols *pCols) {
|
||||||
if (pCols) {
|
if (pCols) {
|
||||||
if (pCols->cols) {
|
if (pCols->cols) {
|
||||||
int maxCols = pCols->maxCols;
|
int maxCols = pCols->maxCols;
|
||||||
for (i = 0; i < maxCols; i++) {
|
for (i = 0; i < maxCols; ++i) {
|
||||||
SDataCol *pCol = &pCols->cols[i];
|
SDataCol *pCol = &pCols->cols[i];
|
||||||
taosMemoryFreeClear(pCol->pData);
|
taosMemoryFreeClear(pCol->pData);
|
||||||
}
|
}
|
||||||
|
@ -464,7 +472,7 @@ SDataCols *tdDupDataCols(SDataCols *pDataCols, bool keepData) {
|
||||||
void tdResetDataCols(SDataCols *pCols) {
|
void tdResetDataCols(SDataCols *pCols) {
|
||||||
if (pCols != NULL) {
|
if (pCols != NULL) {
|
||||||
pCols->numOfRows = 0;
|
pCols->numOfRows = 0;
|
||||||
for (int i = 0; i < pCols->maxCols; i++) {
|
for (int i = 0; i < pCols->maxCols; ++i) {
|
||||||
dataColReset(pCols->cols + i);
|
dataColReset(pCols->cols + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,7 +367,7 @@ void *tDeserializeSVCreateTbReq(void *buf, SVCreateTbReq *pReq) {
|
||||||
buf = taosDecodeFixedI16(buf, &(pReq->stbCfg.nCols));
|
buf = taosDecodeFixedI16(buf, &(pReq->stbCfg.nCols));
|
||||||
buf = taosDecodeFixedI16(buf, &(pReq->stbCfg.nBSmaCols));
|
buf = taosDecodeFixedI16(buf, &(pReq->stbCfg.nBSmaCols));
|
||||||
pReq->stbCfg.pSchema = (SSchemaEx *)taosMemoryMalloc(pReq->stbCfg.nCols * sizeof(SSchemaEx));
|
pReq->stbCfg.pSchema = (SSchemaEx *)taosMemoryMalloc(pReq->stbCfg.nCols * sizeof(SSchemaEx));
|
||||||
for (col_id_t i = 0; i < pReq->stbCfg.nCols; i++) {
|
for (col_id_t i = 0; i < pReq->stbCfg.nCols; ++i) {
|
||||||
buf = taosDecodeFixedI8(buf, &(pReq->stbCfg.pSchema[i].type));
|
buf = taosDecodeFixedI8(buf, &(pReq->stbCfg.pSchema[i].type));
|
||||||
buf = taosDecodeFixedI8(buf, &(pReq->stbCfg.pSchema[i].sma));
|
buf = taosDecodeFixedI8(buf, &(pReq->stbCfg.pSchema[i].sma));
|
||||||
buf = taosDecodeFixedI16(buf, &(pReq->stbCfg.pSchema[i].colId));
|
buf = taosDecodeFixedI16(buf, &(pReq->stbCfg.pSchema[i].colId));
|
||||||
|
@ -376,7 +376,7 @@ void *tDeserializeSVCreateTbReq(void *buf, SVCreateTbReq *pReq) {
|
||||||
}
|
}
|
||||||
buf = taosDecodeFixedI16(buf, &pReq->stbCfg.nTagCols);
|
buf = taosDecodeFixedI16(buf, &pReq->stbCfg.nTagCols);
|
||||||
pReq->stbCfg.pTagSchema = (SSchema *)taosMemoryMalloc(pReq->stbCfg.nTagCols * sizeof(SSchema));
|
pReq->stbCfg.pTagSchema = (SSchema *)taosMemoryMalloc(pReq->stbCfg.nTagCols * sizeof(SSchema));
|
||||||
for (col_id_t i = 0; i < pReq->stbCfg.nTagCols; i++) {
|
for (col_id_t i = 0; i < pReq->stbCfg.nTagCols; ++i) {
|
||||||
buf = taosDecodeFixedI8(buf, &(pReq->stbCfg.pTagSchema[i].type));
|
buf = taosDecodeFixedI8(buf, &(pReq->stbCfg.pTagSchema[i].type));
|
||||||
buf = taosDecodeFixedI16(buf, &pReq->stbCfg.pTagSchema[i].colId);
|
buf = taosDecodeFixedI16(buf, &pReq->stbCfg.pTagSchema[i].colId);
|
||||||
buf = taosDecodeFixedI32(buf, &pReq->stbCfg.pTagSchema[i].bytes);
|
buf = taosDecodeFixedI32(buf, &pReq->stbCfg.pTagSchema[i].bytes);
|
||||||
|
@ -408,7 +408,7 @@ void *tDeserializeSVCreateTbReq(void *buf, SVCreateTbReq *pReq) {
|
||||||
buf = taosDecodeFixedI16(buf, &pReq->ntbCfg.nCols);
|
buf = taosDecodeFixedI16(buf, &pReq->ntbCfg.nCols);
|
||||||
buf = taosDecodeFixedI16(buf, &(pReq->ntbCfg.nBSmaCols));
|
buf = taosDecodeFixedI16(buf, &(pReq->ntbCfg.nBSmaCols));
|
||||||
pReq->ntbCfg.pSchema = (SSchemaEx *)taosMemoryMalloc(pReq->ntbCfg.nCols * sizeof(SSchemaEx));
|
pReq->ntbCfg.pSchema = (SSchemaEx *)taosMemoryMalloc(pReq->ntbCfg.nCols * sizeof(SSchemaEx));
|
||||||
for (col_id_t i = 0; i < pReq->ntbCfg.nCols; i++) {
|
for (col_id_t i = 0; i < pReq->ntbCfg.nCols; ++i) {
|
||||||
buf = taosDecodeFixedI8(buf, &pReq->ntbCfg.pSchema[i].type);
|
buf = taosDecodeFixedI8(buf, &pReq->ntbCfg.pSchema[i].type);
|
||||||
buf = taosDecodeFixedI8(buf, &pReq->ntbCfg.pSchema[i].sma);
|
buf = taosDecodeFixedI8(buf, &pReq->ntbCfg.pSchema[i].sma);
|
||||||
buf = taosDecodeFixedI16(buf, &pReq->ntbCfg.pSchema[i].colId);
|
buf = taosDecodeFixedI16(buf, &pReq->ntbCfg.pSchema[i].colId);
|
||||||
|
@ -2770,6 +2770,48 @@ int32_t tDecodeSMqCMCommitOffsetReq(SCoder *decoder, SMqCMCommitOffsetReq *pReq)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t tSerializeSExplainRsp(void* buf, int32_t bufLen, SExplainRsp* pRsp) {
|
||||||
|
SCoder encoder = {0};
|
||||||
|
tCoderInit(&encoder, TD_LITTLE_ENDIAN, buf, bufLen, TD_ENCODER);
|
||||||
|
|
||||||
|
if (tStartEncode(&encoder) < 0) return -1;
|
||||||
|
if (tEncodeI32(&encoder, pRsp->numOfPlans) < 0) return -1;
|
||||||
|
for (int32_t i = 0; i < pRsp->numOfPlans; ++i) {
|
||||||
|
SExplainExecInfo *info = &pRsp->subplanInfo[i];
|
||||||
|
if (tEncodeU64(&encoder, info->startupCost) < 0) return -1;
|
||||||
|
if (tEncodeU64(&encoder, info->totalCost) < 0) return -1;
|
||||||
|
if (tEncodeU64(&encoder, info->numOfRows) < 0) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tEndEncode(&encoder);
|
||||||
|
|
||||||
|
int32_t tlen = encoder.pos;
|
||||||
|
tCoderClear(&encoder);
|
||||||
|
return tlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tDeserializeSExplainRsp(void* buf, int32_t bufLen, SExplainRsp* pRsp) {
|
||||||
|
SCoder decoder = {0};
|
||||||
|
tCoderInit(&decoder, TD_LITTLE_ENDIAN, buf, bufLen, TD_DECODER);
|
||||||
|
|
||||||
|
if (tStartDecode(&decoder) < 0) return -1;
|
||||||
|
if (tDecodeI32(&decoder, &pRsp->numOfPlans) < 0) return -1;
|
||||||
|
if (pRsp->numOfPlans > 0) {
|
||||||
|
pRsp->subplanInfo = taosMemoryMalloc(pRsp->numOfPlans * sizeof(SExplainExecInfo));
|
||||||
|
if (pRsp->subplanInfo == NULL) return -1;
|
||||||
|
}
|
||||||
|
for (int32_t i = 0; i < pRsp->numOfPlans; ++i) {
|
||||||
|
if (tDecodeU64(&decoder, &pRsp->subplanInfo[i].startupCost) < 0) return -1;
|
||||||
|
if (tDecodeU64(&decoder, &pRsp->subplanInfo[i].totalCost) < 0) return -1;
|
||||||
|
if (tDecodeU64(&decoder, &pRsp->subplanInfo[i].numOfRows) < 0) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tEndDecode(&decoder);
|
||||||
|
|
||||||
|
tCoderClear(&decoder);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t tSerializeSSchedulerHbReq(void *buf, int32_t bufLen, SSchedulerHbReq *pReq) {
|
int32_t tSerializeSSchedulerHbReq(void *buf, int32_t bufLen, SSchedulerHbReq *pReq) {
|
||||||
int32_t headLen = sizeof(SMsgHead);
|
int32_t headLen = sizeof(SMsgHead);
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
|
|
|
@ -503,7 +503,7 @@ SDataCols *tdDupDataCols(SDataCols *pDataCols, bool keepData) {
|
||||||
memcpy(pRet->cols[i].dataOff, pDataCols->cols[i].dataOff, dataOffSize);
|
memcpy(pRet->cols[i].dataOff, pDataCols->cols[i].dataOff, dataOffSize);
|
||||||
}
|
}
|
||||||
if (!TD_COL_ROWS_NORM(pRet->cols + i)) {
|
if (!TD_COL_ROWS_NORM(pRet->cols + i)) {
|
||||||
int32_t nBitmapBytes = (int32_t)TD_BITMAP_BYTES(pDataCols->maxPoints);
|
int32_t nBitmapBytes = (int32_t)TD_BITMAP_BYTES(pDataCols->numOfRows);
|
||||||
memcpy(pRet->cols[i].pBitmap, pDataCols->cols[i].pBitmap, nBitmapBytes);
|
memcpy(pRet->cols[i].pBitmap, pDataCols->cols[i].pBitmap, nBitmapBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1014,4 +1014,28 @@ int32_t taosVariantTypeSetType(SVariant *pVariant, char type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char * taosVariantGet(SVariant *pVar, int32_t type) {
|
||||||
|
switch (type) {
|
||||||
|
case TSDB_DATA_TYPE_BOOL:
|
||||||
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
return (char *)&pVar->i;
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
case TSDB_DATA_TYPE_FLOAT:
|
||||||
|
return (char *)&pVar->d;
|
||||||
|
case TSDB_DATA_TYPE_BINARY:
|
||||||
|
return (char *)pVar->pz;
|
||||||
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
|
return (char *)pVar->ucs4;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
aux_source_directory(dm/src DNODE_SRC)
|
aux_source_directory(dm DNODE_SRC)
|
||||||
aux_source_directory(qm/src DNODE_SRC)
|
aux_source_directory(qm DNODE_SRC)
|
||||||
aux_source_directory(bm/src DNODE_SRC)
|
aux_source_directory(bm DNODE_SRC)
|
||||||
aux_source_directory(sm/src DNODE_SRC)
|
aux_source_directory(sm DNODE_SRC)
|
||||||
aux_source_directory(vm/src DNODE_SRC)
|
aux_source_directory(vm DNODE_SRC)
|
||||||
aux_source_directory(mm/src DNODE_SRC)
|
aux_source_directory(mm DNODE_SRC)
|
||||||
aux_source_directory(main/src DNODE_SRC)
|
aux_source_directory(main DNODE_SRC)
|
||||||
add_library(dnode STATIC ${DNODE_SRC})
|
add_library(dnode STATIC ${DNODE_SRC})
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
dnode cjson mnode vnode qnode snode bnode wal sync taos tfs monitor
|
dnode cjson mnode vnode qnode snode bnode wal sync taos tfs monitor
|
||||||
|
@ -12,20 +12,14 @@ target_link_libraries(
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
dnode
|
dnode
|
||||||
PUBLIC "${CMAKE_SOURCE_DIR}/include/dnode/mgmt"
|
PUBLIC "${CMAKE_SOURCE_DIR}/include/dnode/mgmt"
|
||||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/dm/inc"
|
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
|
||||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/qm/inc"
|
|
||||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/bm/inc"
|
|
||||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/sm/inc"
|
|
||||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/vm/inc"
|
|
||||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/mm/inc"
|
|
||||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/main/inc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
aux_source_directory(main/exe EXEC_SRC)
|
aux_source_directory(exe EXEC_SRC)
|
||||||
add_executable(taosd ${EXEC_SRC})
|
add_executable(taosd ${EXEC_SRC})
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
taosd
|
taosd
|
||||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/main/inc"
|
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
|
||||||
)
|
)
|
||||||
target_link_libraries(taosd dnode)
|
target_link_libraries(taosd dnode)
|
||||||
|
|
||||||
|
|
|
@ -54,4 +54,4 @@ int32_t bmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bmInitMsgHandles(SMgmtWrapper *pWrapper) {}
|
void bmInitMsgHandle(SMgmtWrapper *pWrapper) {}
|
|
@ -109,7 +109,7 @@ int32_t bmOpen(SMgmtWrapper *pWrapper) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bmGetMgmtFp(SMgmtWrapper *pWrapper) {
|
void bmSetMgmtFp(SMgmtWrapper *pWrapper) {
|
||||||
SMgmtFp mgmtFp = {0};
|
SMgmtFp mgmtFp = {0};
|
||||||
mgmtFp.openFp = bmOpen;
|
mgmtFp.openFp = bmOpen;
|
||||||
mgmtFp.closeFp = bmClose;
|
mgmtFp.closeFp = bmClose;
|
||||||
|
@ -117,7 +117,7 @@ void bmGetMgmtFp(SMgmtWrapper *pWrapper) {
|
||||||
mgmtFp.dropMsgFp = bmProcessDropReq;
|
mgmtFp.dropMsgFp = bmProcessDropReq;
|
||||||
mgmtFp.requiredFp = bmRequire;
|
mgmtFp.requiredFp = bmRequire;
|
||||||
|
|
||||||
bmInitMsgHandles(pWrapper);
|
bmInitMsgHandle(pWrapper);
|
||||||
pWrapper->name = "bnode";
|
pWrapper->name = "bnode";
|
||||||
pWrapper->fp = mgmtFp;
|
pWrapper->fp = mgmtFp;
|
||||||
}
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
static void bmSendErrorRsp(SMgmtWrapper *pWrapper, SNodeMsg *pMsg, int32_t code) {
|
static void bmSendErrorRsp(SMgmtWrapper *pWrapper, SNodeMsg *pMsg, int32_t code) {
|
||||||
SRpcMsg rpcRsp = {.handle = pMsg->rpcMsg.handle, .ahandle = pMsg->rpcMsg.ahandle, .code = code};
|
SRpcMsg rpcRsp = {.handle = pMsg->rpcMsg.handle, .ahandle = pMsg->rpcMsg.ahandle, .code = code};
|
||||||
dndSendRsp(pWrapper, &rpcRsp);
|
tmsgSendRsp(&rpcRsp);
|
||||||
|
|
||||||
dTrace("msg:%p, is freed", pMsg);
|
dTrace("msg:%p, is freed", pMsg);
|
||||||
rpcFreeCont(pMsg->rpcMsg.pCont);
|
rpcFreeCont(pMsg->rpcMsg.pCont);
|
|
@ -1,31 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _TD_DND_BNODE_H_
|
|
||||||
#define _TD_DND_BNODE_H_
|
|
||||||
|
|
||||||
#include "dnd.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void bmGetMgmtFp(SMgmtWrapper *pWrapper);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*_TD_DND_BNODE_H_*/
|
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "dmInt.h"
|
#include "dmInt.h"
|
||||||
#include "vm.h"
|
|
||||||
|
|
||||||
void dmSendStatusReq(SDnodeMgmt *pMgmt) {
|
void dmSendStatusReq(SDnodeMgmt *pMgmt) {
|
||||||
SDnode *pDnode = pMgmt->pDnode;
|
SDnode *pDnode = pMgmt->pDnode;
|
||||||
|
@ -57,7 +56,9 @@ void dmSendStatusReq(SDnodeMgmt *pMgmt) {
|
||||||
pMgmt->statusSent = 1;
|
pMgmt->statusSent = 1;
|
||||||
|
|
||||||
dTrace("send req:%s to mnode, app:%p", TMSG_INFO(rpcMsg.msgType), rpcMsg.ahandle);
|
dTrace("send req:%s to mnode, app:%p", TMSG_INFO(rpcMsg.msgType), rpcMsg.ahandle);
|
||||||
dndSendReqToMnode(pMgmt->pWrapper, &rpcMsg);
|
SEpSet epSet = {0};
|
||||||
|
dmGetMnodeEpSet(pMgmt, &epSet);
|
||||||
|
tmsgSendReq(&pMgmt->msgCb, &epSet, &rpcMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dmUpdateDnodeCfg(SDnodeMgmt *pMgmt, SDnodeCfg *pCfg) {
|
static void dmUpdateDnodeCfg(SDnodeMgmt *pMgmt, SDnodeCfg *pCfg) {
|
||||||
|
@ -117,21 +118,99 @@ int32_t dmProcessConfigReq(SDnodeMgmt *pMgmt, SNodeMsg *pMsg) {
|
||||||
return TSDB_CODE_OPS_NOT_SUPPORT;
|
return TSDB_CODE_OPS_NOT_SUPPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmInitMsgHandles(SMgmtWrapper *pWrapper) {
|
|
||||||
|
static int32_t dmProcessCreateNodeMsg(SDnode *pDnode, ENodeType ntype, SNodeMsg *pMsg) {
|
||||||
|
SMgmtWrapper *pWrapper = dndAcquireWrapper(pDnode, ntype);
|
||||||
|
if (pWrapper != NULL) {
|
||||||
|
dndReleaseWrapper(pWrapper);
|
||||||
|
terrno = TSDB_CODE_NODE_ALREADY_DEPLOYED;
|
||||||
|
dError("failed to create node since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pWrapper = &pDnode->wrappers[ntype];
|
||||||
|
|
||||||
|
if (taosMkDir(pWrapper->path) != 0) {
|
||||||
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
dError("failed to create dir:%s since %s", pWrapper->path, terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = (*pWrapper->fp.createMsgFp)(pWrapper, pMsg);
|
||||||
|
if (code != 0) {
|
||||||
|
dError("node:%s, failed to open since %s", pWrapper->name, terrstr());
|
||||||
|
} else {
|
||||||
|
dDebug("node:%s, has been opened", pWrapper->name);
|
||||||
|
pWrapper->deployed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dmProcessDropNodeMsg(SDnode *pDnode, ENodeType ntype, SNodeMsg *pMsg) {
|
||||||
|
SMgmtWrapper *pWrapper = dndAcquireWrapper(pDnode, ntype);
|
||||||
|
if (pWrapper == NULL) {
|
||||||
|
terrno = TSDB_CODE_NODE_NOT_DEPLOYED;
|
||||||
|
dError("failed to drop node since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosWLockLatch(&pWrapper->latch);
|
||||||
|
pWrapper->deployed = false;
|
||||||
|
|
||||||
|
int32_t code = (*pWrapper->fp.dropMsgFp)(pWrapper, pMsg);
|
||||||
|
if (code != 0) {
|
||||||
|
pWrapper->deployed = true;
|
||||||
|
dError("node:%s, failed to drop since %s", pWrapper->name, terrstr());
|
||||||
|
} else {
|
||||||
|
pWrapper->deployed = false;
|
||||||
|
dDebug("node:%s, has been dropped", pWrapper->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosWUnLockLatch(&pWrapper->latch);
|
||||||
|
dndReleaseWrapper(pWrapper);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t dmProcessCDnodeReq(SDnode *pDnode, SNodeMsg *pMsg) {
|
||||||
|
switch (pMsg->rpcMsg.msgType) {
|
||||||
|
case TDMT_DND_CREATE_MNODE:
|
||||||
|
return dmProcessCreateNodeMsg(pDnode, MNODE, pMsg);
|
||||||
|
case TDMT_DND_DROP_MNODE:
|
||||||
|
return dmProcessDropNodeMsg(pDnode, MNODE, pMsg);
|
||||||
|
case TDMT_DND_CREATE_QNODE:
|
||||||
|
return dmProcessCreateNodeMsg(pDnode, QNODE, pMsg);
|
||||||
|
case TDMT_DND_DROP_QNODE:
|
||||||
|
return dmProcessDropNodeMsg(pDnode, QNODE, pMsg);
|
||||||
|
case TDMT_DND_CREATE_SNODE:
|
||||||
|
return dmProcessCreateNodeMsg(pDnode, SNODE, pMsg);
|
||||||
|
case TDMT_DND_DROP_SNODE:
|
||||||
|
return dmProcessDropNodeMsg(pDnode, SNODE, pMsg);
|
||||||
|
case TDMT_DND_CREATE_BNODE:
|
||||||
|
return dmProcessCreateNodeMsg(pDnode, BNODE, pMsg);
|
||||||
|
case TDMT_DND_DROP_BNODE:
|
||||||
|
return dmProcessDropNodeMsg(pDnode, BNODE, pMsg);
|
||||||
|
default:
|
||||||
|
terrno = TSDB_CODE_MSG_NOT_PROCESSED;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dmInitMsgHandle(SMgmtWrapper *pWrapper) {
|
||||||
// Requests handled by DNODE
|
// Requests handled by DNODE
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_MNODE, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_MNODE, dmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_MNODE, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_MNODE, dmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_QNODE, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_QNODE, dmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_QNODE, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_QNODE, dmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_SNODE, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_SNODE, dmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_SNODE, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_SNODE, dmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_BNODE, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_BNODE, dmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_BNODE, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_BNODE, dmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_CONFIG_DNODE, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_CONFIG_DNODE, dmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_NETWORK_TEST, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_NETWORK_TEST, dmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
|
|
||||||
// Requests handled by MNODE
|
// Requests handled by MNODE
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_STATUS_RSP, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_STATUS_RSP, dmProcessStatusMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_GRANT_RSP, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_GRANT_RSP, dmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_AUTH_RSP, dmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_AUTH_RSP, dmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
}
|
}
|
|
@ -78,7 +78,7 @@ static int32_t dmStart(SMgmtWrapper *pWrapper) {
|
||||||
return dmStartThread(pWrapper->pMgmt);
|
return dmStartThread(pWrapper->pMgmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t dmInit(SMgmtWrapper *pWrapper) {
|
static int32_t dmInit(SMgmtWrapper *pWrapper) {
|
||||||
SDnode *pDnode = pWrapper->pDnode;
|
SDnode *pDnode = pWrapper->pDnode;
|
||||||
SDnodeMgmt *pMgmt = taosMemoryCalloc(1, sizeof(SDnodeMgmt));
|
SDnodeMgmt *pMgmt = taosMemoryCalloc(1, sizeof(SDnodeMgmt));
|
||||||
dInfo("dnode-mgmt start to init");
|
dInfo("dnode-mgmt start to init");
|
||||||
|
@ -112,22 +112,19 @@ int32_t dmInit(SMgmtWrapper *pWrapper) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dndInitServer(pDnode) != 0) {
|
if (dndInitTrans(pDnode) != 0) {
|
||||||
dError("failed to init trans server since %s", terrstr());
|
dError("failed to init transport since %s", terrstr());
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dndInitClient(pDnode) != 0) {
|
|
||||||
dError("failed to init trans client since %s", terrstr());
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pWrapper->pMgmt = pMgmt;
|
pWrapper->pMgmt = pMgmt;
|
||||||
|
pMgmt->msgCb = dndCreateMsgcb(pWrapper);
|
||||||
|
|
||||||
dInfo("dnode-mgmt is initialized");
|
dInfo("dnode-mgmt is initialized");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmCleanup(SMgmtWrapper *pWrapper) {
|
static void dmCleanup(SMgmtWrapper *pWrapper) {
|
||||||
SDnodeMgmt *pMgmt = pWrapper->pMgmt;
|
SDnodeMgmt *pMgmt = pWrapper->pMgmt;
|
||||||
if (pMgmt == NULL) return;
|
if (pMgmt == NULL) return;
|
||||||
|
|
||||||
|
@ -151,25 +148,24 @@ void dmCleanup(SMgmtWrapper *pWrapper) {
|
||||||
|
|
||||||
taosMemoryFree(pMgmt);
|
taosMemoryFree(pMgmt);
|
||||||
pWrapper->pMgmt = NULL;
|
pWrapper->pMgmt = NULL;
|
||||||
dndCleanupServer(pDnode);
|
dndCleanupTrans(pDnode);
|
||||||
dndCleanupClient(pDnode);
|
|
||||||
|
|
||||||
dInfo("dnode-mgmt is cleaned up");
|
dInfo("dnode-mgmt is cleaned up");
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t dmRequire(SMgmtWrapper *pWrapper, bool *required) {
|
static int32_t dmRequire(SMgmtWrapper *pWrapper, bool *required) {
|
||||||
*required = true;
|
*required = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmGetMgmtFp(SMgmtWrapper *pWrapper) {
|
void dmSetMgmtFp(SMgmtWrapper *pWrapper) {
|
||||||
SMgmtFp mgmtFp = {0};
|
SMgmtFp mgmtFp = {0};
|
||||||
mgmtFp.openFp = dmInit;
|
mgmtFp.openFp = dmInit;
|
||||||
mgmtFp.closeFp = dmCleanup;
|
mgmtFp.closeFp = dmCleanup;
|
||||||
mgmtFp.startFp = dmStart;
|
mgmtFp.startFp = dmStart;
|
||||||
mgmtFp.requiredFp = dmRequire;
|
mgmtFp.requiredFp = dmRequire;
|
||||||
|
|
||||||
dmInitMsgHandles(pWrapper);
|
dmInitMsgHandle(pWrapper);
|
||||||
pWrapper->name = "dnode";
|
pWrapper->name = "dnode";
|
||||||
pWrapper->fp = mgmtFp;
|
pWrapper->fp = mgmtFp;
|
||||||
}
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "dndInt.h"
|
#include "dndInt.h"
|
||||||
|
|
||||||
static int32_t dndGetMonitorDiskInfo(SDnode *pDnode, SMonDiskInfo *pInfo) {
|
static int32_t dmGetMonitorDiskInfo(SDnode *pDnode, SMonDiskInfo *pInfo) {
|
||||||
tstrncpy(pInfo->logdir.name, tsLogDir, sizeof(pInfo->logdir.name));
|
tstrncpy(pInfo->logdir.name, tsLogDir, sizeof(pInfo->logdir.name));
|
||||||
pInfo->logdir.size = tsLogSpace.size;
|
pInfo->logdir.size = tsLogSpace.size;
|
||||||
tstrncpy(pInfo->tempdir.name, tsTempDir, sizeof(pInfo->tempdir.name));
|
tstrncpy(pInfo->tempdir.name, tsTempDir, sizeof(pInfo->tempdir.name));
|
||||||
|
@ -30,14 +30,14 @@ static int32_t dndGetMonitorDiskInfo(SDnode *pDnode, SMonDiskInfo *pInfo) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dndGetMonitorBasicInfo(SDnode *pDnode, SMonBasicInfo *pInfo) {
|
static void dmGetMonitorBasicInfo(SDnode *pDnode, SMonBasicInfo *pInfo) {
|
||||||
pInfo->protocol = 1;
|
pInfo->protocol = 1;
|
||||||
pInfo->dnode_id = pDnode->dnodeId;
|
pInfo->dnode_id = pDnode->dnodeId;
|
||||||
pInfo->cluster_id = pDnode->clusterId;
|
pInfo->cluster_id = pDnode->clusterId;
|
||||||
tstrncpy(pInfo->dnode_ep, tsLocalEp, TSDB_EP_LEN);
|
tstrncpy(pInfo->dnode_ep, tsLocalEp, TSDB_EP_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dndGetMonitorDnodeInfo(SDnode *pDnode, SMonDnodeInfo *pInfo) {
|
static void dmGetMonitorDnodeInfo(SDnode *pDnode, SMonDnodeInfo *pInfo) {
|
||||||
pInfo->uptime = (taosGetTimestampMs() - pDnode->rebootTime) / (86400000.0f);
|
pInfo->uptime = (taosGetTimestampMs() - pDnode->rebootTime) / (86400000.0f);
|
||||||
taosGetCpuUsage(&pInfo->cpu_engine, &pInfo->cpu_system);
|
taosGetCpuUsage(&pInfo->cpu_engine, &pInfo->cpu_system);
|
||||||
taosGetCpuCores(&pInfo->cpu_cores);
|
taosGetCpuCores(&pInfo->cpu_cores);
|
||||||
|
@ -63,7 +63,7 @@ static void dndGetMonitorDnodeInfo(SDnode *pDnode, SMonDnodeInfo *pInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dndSendMonitorReport(SDnode *pDnode) {
|
void dmSendMonitorReport(SDnode *pDnode) {
|
||||||
if (!tsEnableMonitor || tsMonitorFqdn[0] == 0 || tsMonitorPort == 0) return;
|
if (!tsEnableMonitor || tsMonitorFqdn[0] == 0 || tsMonitorPort == 0) return;
|
||||||
dTrace("send monitor report to %s:%u", tsMonitorFqdn, tsMonitorPort);
|
dTrace("send monitor report to %s:%u", tsMonitorFqdn, tsMonitorPort);
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ void dndSendMonitorReport(SDnode *pDnode) {
|
||||||
if (pMonitor == NULL) return;
|
if (pMonitor == NULL) return;
|
||||||
|
|
||||||
SMonBasicInfo basicInfo = {0};
|
SMonBasicInfo basicInfo = {0};
|
||||||
dndGetMonitorBasicInfo(pDnode, &basicInfo);
|
dmGetMonitorBasicInfo(pDnode, &basicInfo);
|
||||||
monSetBasicInfo(pMonitor, &basicInfo);
|
monSetBasicInfo(pMonitor, &basicInfo);
|
||||||
|
|
||||||
SMonClusterInfo clusterInfo = {0};
|
SMonClusterInfo clusterInfo = {0};
|
||||||
|
@ -89,11 +89,11 @@ void dndSendMonitorReport(SDnode *pDnode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SMonDnodeInfo dnodeInfo = {0};
|
SMonDnodeInfo dnodeInfo = {0};
|
||||||
dndGetMonitorDnodeInfo(pDnode, &dnodeInfo);
|
dmGetMonitorDnodeInfo(pDnode, &dnodeInfo);
|
||||||
monSetDnodeInfo(pMonitor, &dnodeInfo);
|
monSetDnodeInfo(pMonitor, &dnodeInfo);
|
||||||
|
|
||||||
SMonDiskInfo diskInfo = {0};
|
SMonDiskInfo diskInfo = {0};
|
||||||
if (dndGetMonitorDiskInfo(pDnode, &diskInfo) == 0) {
|
if (dmGetMonitorDiskInfo(pDnode, &diskInfo) == 0) {
|
||||||
monSetDiskInfo(pMonitor, &diskInfo);
|
monSetDiskInfo(pMonitor, &diskInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,16 +14,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "bm.h"
|
|
||||||
#include "dmInt.h"
|
#include "dmInt.h"
|
||||||
#include "mm.h"
|
|
||||||
#include "qm.h"
|
|
||||||
#include "sm.h"
|
|
||||||
#include "vm.h"
|
|
||||||
|
|
||||||
static void *dmThreadRoutine(void *param) {
|
static void *dmThreadRoutine(void *param) {
|
||||||
SDnodeMgmt *pMgmt = param;
|
SDnodeMgmt *pMgmt = param;
|
||||||
SDnode * pDnode = pMgmt->pDnode;
|
SDnode *pDnode = pMgmt->pDnode;
|
||||||
int64_t lastStatusTime = taosGetTimestampMs();
|
int64_t lastStatusTime = taosGetTimestampMs();
|
||||||
int64_t lastMonitorTime = lastStatusTime;
|
int64_t lastMonitorTime = lastStatusTime;
|
||||||
|
|
||||||
|
@ -37,8 +32,7 @@ static void *dmThreadRoutine(void *param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t curTime = taosGetTimestampMs();
|
int64_t curTime = taosGetTimestampMs();
|
||||||
|
float statusInterval = (curTime - lastStatusTime) / 1000.0f;
|
||||||
float statusInterval = (curTime - lastStatusTime) / 1000.0f;
|
|
||||||
if (statusInterval >= tsStatusInterval && !pMgmt->statusSent) {
|
if (statusInterval >= tsStatusInterval && !pMgmt->statusSent) {
|
||||||
dmSendStatusReq(pMgmt);
|
dmSendStatusReq(pMgmt);
|
||||||
lastStatusTime = curTime;
|
lastStatusTime = curTime;
|
||||||
|
@ -46,32 +40,33 @@ static void *dmThreadRoutine(void *param) {
|
||||||
|
|
||||||
float monitorInterval = (curTime - lastMonitorTime) / 1000.0f;
|
float monitorInterval = (curTime - lastMonitorTime) / 1000.0f;
|
||||||
if (monitorInterval >= tsMonitorInterval) {
|
if (monitorInterval >= tsMonitorInterval) {
|
||||||
dndSendMonitorReport(pDnode);
|
dmSendMonitorReport(pDnode);
|
||||||
lastMonitorTime = curTime;
|
lastMonitorTime = curTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t dmStartThread(SDnodeMgmt *pMgmt) {
|
||||||
|
pMgmt->threadId = taosCreateThread(dmThreadRoutine, pMgmt);
|
||||||
|
if (pMgmt->threadId == NULL) {
|
||||||
|
dError("failed to init dnode thread");
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void dmProcessQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) {
|
static void dmProcessQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) {
|
||||||
SDnodeMgmt *pMgmt = pInfo->ahandle;
|
SDnodeMgmt *pMgmt = pInfo->ahandle;
|
||||||
|
|
||||||
SDnode * pDnode = pMgmt->pDnode;
|
SDnode *pDnode = pMgmt->pDnode;
|
||||||
SRpcMsg *pRpc = &pMsg->rpcMsg;
|
SRpcMsg *pRpc = &pMsg->rpcMsg;
|
||||||
int32_t code = -1;
|
int32_t code = -1;
|
||||||
dTrace("msg:%p, will be processed in dnode queue", pMsg);
|
dTrace("msg:%p, will be processed in dnode queue", pMsg);
|
||||||
|
|
||||||
switch (pRpc->msgType) {
|
switch (pRpc->msgType) {
|
||||||
case TDMT_DND_CREATE_MNODE:
|
|
||||||
case TDMT_DND_CREATE_QNODE:
|
|
||||||
case TDMT_DND_CREATE_SNODE:
|
|
||||||
case TDMT_DND_CREATE_BNODE:
|
|
||||||
case TDMT_DND_DROP_MNODE:
|
|
||||||
case TDMT_DND_DROP_QNODE:
|
|
||||||
case TDMT_DND_DROP_SNODE:
|
|
||||||
case TDMT_DND_DROP_BNODE:
|
|
||||||
code = dndProcessNodeMsg(pMgmt->pDnode, pMsg);
|
|
||||||
break;
|
|
||||||
case TDMT_DND_CONFIG_DNODE:
|
case TDMT_DND_CONFIG_DNODE:
|
||||||
code = dmProcessConfigReq(pMgmt, pMsg);
|
code = dmProcessConfigReq(pMgmt, pMsg);
|
||||||
break;
|
break;
|
||||||
|
@ -85,8 +80,8 @@ static void dmProcessQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) {
|
||||||
code = dmProcessGrantRsp(pMgmt, pMsg);
|
code = dmProcessGrantRsp(pMgmt, pMsg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
terrno = TSDB_CODE_MSG_NOT_PROCESSED;
|
code = dmProcessCDnodeReq(pMgmt->pDnode, pMsg);
|
||||||
dError("msg:%p, type:%s not processed in dnode queue", pRpc->handle, TMSG_INFO(pRpc->msgType));
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pRpc->msgType & 1u) {
|
if (pRpc->msgType & 1u) {
|
||||||
|
@ -101,16 +96,14 @@ static void dmProcessQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t dmStartWorker(SDnodeMgmt *pMgmt) {
|
int32_t dmStartWorker(SDnodeMgmt *pMgmt) {
|
||||||
SSingleWorkerCfg mgmtCfg = {
|
SSingleWorkerCfg mcfg = {.min = 1, .max = 1, .name = "dnode-mgmt", .fp = (FItem)dmProcessQueue, .param = pMgmt};
|
||||||
.min = 1, .max = 1, .name = "dnode-mgmt", .fp = (FItem)dmProcessQueue, .param = pMgmt};
|
if (tSingleWorkerInit(&pMgmt->mgmtWorker, &mcfg) != 0) {
|
||||||
if (tSingleWorkerInit(&pMgmt->mgmtWorker, &mgmtCfg) != 0) {
|
|
||||||
dError("failed to start dnode mgmt worker since %s", terrstr());
|
dError("failed to start dnode mgmt worker since %s", terrstr());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSingleWorkerCfg statusCfg = {
|
SSingleWorkerCfg scfg = {.min = 1, .max = 1, .name = "dnode-status", .fp = (FItem)dmProcessQueue, .param = pMgmt};
|
||||||
.min = 1, .max = 1, .name = "dnode-status", .fp = (FItem)dmProcessQueue, .param = pMgmt};
|
if (tSingleWorkerInit(&pMgmt->statusWorker, &scfg) != 0) {
|
||||||
if (tSingleWorkerInit(&pMgmt->statusWorker, &statusCfg) != 0) {
|
|
||||||
dError("failed to start dnode status worker since %s", terrstr());
|
dError("failed to start dnode status worker since %s", terrstr());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -119,17 +112,6 @@ int32_t dmStartWorker(SDnodeMgmt *pMgmt) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t dmStartThread(SDnodeMgmt *pMgmt) {
|
|
||||||
pMgmt->threadId = taosCreateThread(dmThreadRoutine, pMgmt);
|
|
||||||
if (pMgmt->threadId == NULL) {
|
|
||||||
dError("failed to init dnode thread");
|
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dmStopWorker(SDnodeMgmt *pMgmt) {
|
void dmStopWorker(SDnodeMgmt *pMgmt) {
|
||||||
tSingleWorkerCleanup(&pMgmt->mgmtWorker);
|
tSingleWorkerCleanup(&pMgmt->mgmtWorker);
|
||||||
tSingleWorkerCleanup(&pMgmt->statusWorker);
|
tSingleWorkerCleanup(&pMgmt->statusWorker);
|
||||||
|
@ -144,9 +126,15 @@ void dmStopWorker(SDnodeMgmt *pMgmt) {
|
||||||
int32_t dmProcessMgmtMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) {
|
int32_t dmProcessMgmtMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) {
|
||||||
SDnodeMgmt *pMgmt = pWrapper->pMgmt;
|
SDnodeMgmt *pMgmt = pWrapper->pMgmt;
|
||||||
SSingleWorker *pWorker = &pMgmt->mgmtWorker;
|
SSingleWorker *pWorker = &pMgmt->mgmtWorker;
|
||||||
if (pMsg->rpcMsg.msgType == TDMT_MND_STATUS_RSP) {
|
|
||||||
pWorker = &pMgmt->statusWorker;
|
dTrace("msg:%p, put into worker %s", pMsg, pWorker->name);
|
||||||
}
|
taosWriteQitem(pWorker->queue, pMsg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t dmProcessStatusMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) {
|
||||||
|
SDnodeMgmt *pMgmt = pWrapper->pMgmt;
|
||||||
|
SSingleWorker *pWorker = &pMgmt->statusWorker;
|
||||||
|
|
||||||
dTrace("msg:%p, put into worker %s", pMsg, pWorker->name);
|
dTrace("msg:%p, put into worker %s", pMsg, pWorker->name);
|
||||||
taosWriteQitem(pWorker->queue, pMsg);
|
taosWriteQitem(pWorker->queue, pMsg);
|
|
@ -1,38 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _TD_DND_DNODE_H_
|
|
||||||
#define _TD_DND_DNODE_H_
|
|
||||||
|
|
||||||
#include "dnd.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct SDnodeMgmt SDnodeMgmt;
|
|
||||||
|
|
||||||
void dmGetMgmtFp(SMgmtWrapper *pWrapper);
|
|
||||||
void dmInitMsgHandles(SMgmtWrapper *pWrapper);
|
|
||||||
|
|
||||||
void dmGetMnodeEpSet(SDnodeMgmt *pMgmt, SEpSet *pEpSet);
|
|
||||||
void dmUpdateMnodeEpSet(SDnodeMgmt *pMgmt, SEpSet *pEpSet);
|
|
||||||
void dmSendRedirectRsp(SDnodeMgmt *pMgmt, const SRpcMsg *pMsg);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*_TD_DND_DNODE_H_*/
|
|
|
@ -14,7 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "dnd.h"
|
#include "dndInt.h"
|
||||||
#include "tconfig.h"
|
#include "tconfig.h"
|
||||||
|
|
||||||
static struct {
|
static struct {
|
|
@ -16,7 +16,7 @@
|
||||||
#ifndef _TD_DND_BNODE_INT_H_
|
#ifndef _TD_DND_BNODE_INT_H_
|
||||||
#define _TD_DND_BNODE_INT_H_
|
#define _TD_DND_BNODE_INT_H_
|
||||||
|
|
||||||
#include "bm.h"
|
#include "dndInt.h"
|
||||||
#include "bnode.h"
|
#include "bnode.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -35,8 +35,8 @@ typedef struct SBnodeMgmt {
|
||||||
int32_t bmOpen(SMgmtWrapper *pWrapper);
|
int32_t bmOpen(SMgmtWrapper *pWrapper);
|
||||||
int32_t bmDrop(SMgmtWrapper *pWrapper);
|
int32_t bmDrop(SMgmtWrapper *pWrapper);
|
||||||
|
|
||||||
// bmMsg.c
|
// bmHandle.c
|
||||||
void bmInitMsgHandles(SMgmtWrapper *pWrapper);
|
void bmInitMsgHandle(SMgmtWrapper *pWrapper);
|
||||||
int32_t bmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
int32_t bmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
||||||
int32_t bmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
int32_t bmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#ifndef _TD_DND_DNODE_INT_H_
|
#ifndef _TD_DND_DNODE_INT_H_
|
||||||
#define _TD_DND_DNODE_INT_H_
|
#define _TD_DND_DNODE_INT_H_
|
||||||
|
|
||||||
#include "dm.h"
|
#include "dndInt.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -33,6 +33,7 @@ typedef struct SDnodeMgmt {
|
||||||
SRWLatch latch;
|
SRWLatch latch;
|
||||||
SSingleWorker mgmtWorker;
|
SSingleWorker mgmtWorker;
|
||||||
SSingleWorker statusWorker;
|
SSingleWorker statusWorker;
|
||||||
|
SMsgCb msgCb;
|
||||||
const char *path;
|
const char *path;
|
||||||
SDnode *pDnode;
|
SDnode *pDnode;
|
||||||
SMgmtWrapper *pWrapper;
|
SMgmtWrapper *pWrapper;
|
||||||
|
@ -43,18 +44,24 @@ int32_t dmReadFile(SDnodeMgmt *pMgmt);
|
||||||
int32_t dmWriteFile(SDnodeMgmt *pMgmt);
|
int32_t dmWriteFile(SDnodeMgmt *pMgmt);
|
||||||
void dmUpdateDnodeEps(SDnodeMgmt *pMgmt, SArray *pDnodeEps);
|
void dmUpdateDnodeEps(SDnodeMgmt *pMgmt, SArray *pDnodeEps);
|
||||||
|
|
||||||
// dmMsg.c
|
// dmHandle.c
|
||||||
|
void dmInitMsgHandle(SMgmtWrapper *pWrapper);
|
||||||
void dmSendStatusReq(SDnodeMgmt *pMgmt);
|
void dmSendStatusReq(SDnodeMgmt *pMgmt);
|
||||||
int32_t dmProcessConfigReq(SDnodeMgmt *pMgmt, SNodeMsg *pMsg);
|
int32_t dmProcessConfigReq(SDnodeMgmt *pMgmt, SNodeMsg *pMsg);
|
||||||
int32_t dmProcessStatusRsp(SDnodeMgmt *pMgmt, SNodeMsg *pMsg);
|
int32_t dmProcessStatusRsp(SDnodeMgmt *pMgmt, SNodeMsg *pMsg);
|
||||||
int32_t dmProcessAuthRsp(SDnodeMgmt *pMgmt, SNodeMsg *pMsg);
|
int32_t dmProcessAuthRsp(SDnodeMgmt *pMgmt, SNodeMsg *pMsg);
|
||||||
int32_t dmProcessGrantRsp(SDnodeMgmt *pMgmt, SNodeMsg *pMsg);
|
int32_t dmProcessGrantRsp(SDnodeMgmt *pMgmt, SNodeMsg *pMsg);
|
||||||
|
int32_t dmProcessCDnodeReq(SDnode *pDnode, SNodeMsg *pMsg);
|
||||||
|
|
||||||
|
// dmMonitor.c
|
||||||
|
void dmSendMonitorReport(SDnode *pDnode);
|
||||||
|
|
||||||
// dmWorker.c
|
// dmWorker.c
|
||||||
|
int32_t dmStartThread(SDnodeMgmt *pMgmt);
|
||||||
int32_t dmStartWorker(SDnodeMgmt *pMgmt);
|
int32_t dmStartWorker(SDnodeMgmt *pMgmt);
|
||||||
void dmStopWorker(SDnodeMgmt *pMgmt);
|
void dmStopWorker(SDnodeMgmt *pMgmt);
|
||||||
int32_t dmStartThread(SDnodeMgmt *pMgmt);
|
|
||||||
int32_t dmProcessMgmtMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
int32_t dmProcessMgmtMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
||||||
|
int32_t dmProcessStatusMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
|
@ -13,8 +13,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TD_DND_H_
|
#ifndef _TD_DND_INT_H_
|
||||||
#define _TD_DND_H_
|
#define _TD_DND_INT_H_
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
@ -27,13 +27,13 @@
|
||||||
#include "tlockfree.h"
|
#include "tlockfree.h"
|
||||||
#include "tlog.h"
|
#include "tlog.h"
|
||||||
#include "tmsg.h"
|
#include "tmsg.h"
|
||||||
|
#include "tmsgcb.h"
|
||||||
#include "tprocess.h"
|
#include "tprocess.h"
|
||||||
#include "tqueue.h"
|
#include "tqueue.h"
|
||||||
#include "trpc.h"
|
#include "trpc.h"
|
||||||
#include "tthread.h"
|
#include "tthread.h"
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
#include "tworker.h"
|
#include "tworker.h"
|
||||||
#include "tmsgcb.h"
|
|
||||||
|
|
||||||
#include "dnode.h"
|
#include "dnode.h"
|
||||||
#include "monitor.h"
|
#include "monitor.h"
|
||||||
|
@ -73,7 +73,7 @@ typedef int32_t (*DropNodeFp)(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
||||||
typedef int32_t (*RequireNodeFp)(SMgmtWrapper *pWrapper, bool *required);
|
typedef int32_t (*RequireNodeFp)(SMgmtWrapper *pWrapper, bool *required);
|
||||||
|
|
||||||
typedef struct SMsgHandle {
|
typedef struct SMsgHandle {
|
||||||
SMgmtWrapper *pQndWrapper;
|
SMgmtWrapper *pQndWrapper;
|
||||||
SMgmtWrapper *pMndWrapper;
|
SMgmtWrapper *pMndWrapper;
|
||||||
SMgmtWrapper *pWrapper;
|
SMgmtWrapper *pWrapper;
|
||||||
} SMsgHandle;
|
} SMsgHandle;
|
||||||
|
@ -92,6 +92,7 @@ typedef struct SMgmtWrapper {
|
||||||
char *path;
|
char *path;
|
||||||
int32_t refCount;
|
int32_t refCount;
|
||||||
SRWLatch latch;
|
SRWLatch latch;
|
||||||
|
ENodeType ntype;
|
||||||
bool deployed;
|
bool deployed;
|
||||||
bool required;
|
bool required;
|
||||||
EProcType procType;
|
EProcType procType;
|
||||||
|
@ -134,44 +135,72 @@ typedef struct SDnode {
|
||||||
SMgmtWrapper wrappers[NODE_MAX];
|
SMgmtWrapper wrappers[NODE_MAX];
|
||||||
} SDnode;
|
} SDnode;
|
||||||
|
|
||||||
// dndFile.h
|
// dndEnv.c
|
||||||
int32_t dndReadFile(SMgmtWrapper *pWrapper, bool *pDeployed);
|
const char *dndStatStr(EDndStatus stat);
|
||||||
int32_t dndWriteFile(SMgmtWrapper *pWrapper, bool deployed);
|
const char *dndNodeLogStr(ENodeType ntype);
|
||||||
|
const char *dndNodeProcStr(ENodeType ntype);
|
||||||
|
const char *dndEventStr(EDndEvent ev);
|
||||||
|
|
||||||
// dndInt.h
|
// dndExec.c
|
||||||
|
int32_t dndOpenNode(SMgmtWrapper *pWrapper);
|
||||||
|
void dndCloseNode(SMgmtWrapper *pWrapper);
|
||||||
|
|
||||||
|
// dndFile.c
|
||||||
|
int32_t dndReadFile(SMgmtWrapper *pWrapper, bool *pDeployed);
|
||||||
|
int32_t dndWriteFile(SMgmtWrapper *pWrapper, bool deployed);
|
||||||
|
TdFilePtr dndCheckRunning(const char *dataDir);
|
||||||
|
int32_t dndReadShmFile(SDnode *pDnode);
|
||||||
|
int32_t dndWriteShmFile(SDnode *pDnode);
|
||||||
|
|
||||||
|
// dndInt.c
|
||||||
EDndStatus dndGetStatus(SDnode *pDnode);
|
EDndStatus dndGetStatus(SDnode *pDnode);
|
||||||
void dndSetStatus(SDnode *pDnode, EDndStatus stat);
|
void dndSetStatus(SDnode *pDnode, EDndStatus stat);
|
||||||
void dndSetMsgHandle(SMgmtWrapper *pWrapper, tmsg_t msgType, NodeMsgFp nodeMsgFp, int8_t vgId);
|
void dndSetMsgHandle(SMgmtWrapper *pWrapper, tmsg_t msgType, NodeMsgFp nodeMsgFp, int8_t vgId);
|
||||||
SMgmtWrapper *dndAcquireWrapper(SDnode *pDnode, ENodeType nodeType);
|
SMgmtWrapper *dndAcquireWrapper(SDnode *pDnode, ENodeType nodeType);
|
||||||
int32_t dndMarkWrapper(SMgmtWrapper *pWrapper);
|
int32_t dndMarkWrapper(SMgmtWrapper *pWrapper);
|
||||||
void dndReleaseWrapper(SMgmtWrapper *pWrapper);
|
void dndReleaseWrapper(SMgmtWrapper *pWrapper);
|
||||||
|
void dndHandleEvent(SDnode *pDnode, EDndEvent event);
|
||||||
|
void dndReportStartup(SDnode *pDnode, const char *pName, const char *pDesc);
|
||||||
|
void dndProcessStartupReq(SDnode *pDnode, SRpcMsg *pMsg);
|
||||||
|
|
||||||
// dndMonitor.h
|
// dndTransport.c
|
||||||
void dndSendMonitorReport(SDnode *pDnode);
|
int32_t dndInitTrans(SDnode *pDnode);
|
||||||
|
void dndCleanupTrans(SDnode *pDnode);
|
||||||
|
SMsgCb dndCreateMsgcb(SMgmtWrapper *pWrapper);
|
||||||
|
SProcCfg dndGenProcCfg(SMgmtWrapper *pWrapper);
|
||||||
|
int32_t dndInitMsgHandle(SDnode *pDnode);
|
||||||
|
|
||||||
// dndMsg.h
|
// mgmt
|
||||||
void dndReportStartup(SDnode *pDnode, const char *pName, const char *pDesc);
|
void dmSetMgmtFp(SMgmtWrapper *pWrapper);
|
||||||
int32_t dndProcessNodeMsg(SDnode *pDnode, SNodeMsg *pMsg);
|
void bmSetMgmtFp(SMgmtWrapper *pWrapper);
|
||||||
|
void qmSetMgmtFp(SMgmtWrapper *pMgmt);
|
||||||
|
void smSetMgmtFp(SMgmtWrapper *pWrapper);
|
||||||
|
void vmSetMgmtFp(SMgmtWrapper *pWrapper);
|
||||||
|
void mmSetMgmtFp(SMgmtWrapper *pMgmt);
|
||||||
|
|
||||||
// dndStr.h
|
void dmGetMnodeEpSet(SDnodeMgmt *pMgmt, SEpSet *pEpSet);
|
||||||
const char *dndStatStr(EDndStatus stat);
|
void dmUpdateMnodeEpSet(SDnodeMgmt *pMgmt, SEpSet *pEpSet);
|
||||||
const char *dndNodeLogStr(ENodeType ntype);
|
void dmSendRedirectRsp(SDnodeMgmt *pMgmt, const SRpcMsg *pMsg);
|
||||||
const char *dndNodeProcStr(ENodeType ntype);
|
|
||||||
const char *dndEventStr(EDndEvent ev);
|
|
||||||
|
|
||||||
// dndTransport.h
|
typedef struct {
|
||||||
int32_t dndInitServer(SDnode *pDnode);
|
int32_t openVnodes;
|
||||||
void dndCleanupServer(SDnode *pDnode);
|
int32_t totalVnodes;
|
||||||
int32_t dndInitClient(SDnode *pDnode);
|
int32_t masterNum;
|
||||||
void dndCleanupClient(SDnode *pDnode);
|
int64_t numOfSelectReqs;
|
||||||
int32_t dndSendReqToMnode(SMgmtWrapper *pWrapper, SRpcMsg *pMsg);
|
int64_t numOfInsertReqs;
|
||||||
int32_t dndSendReq(SMgmtWrapper *pWrapper, const SEpSet *pEpSet, SRpcMsg *pMsg);
|
int64_t numOfInsertSuccessReqs;
|
||||||
void dndSendRsp(SMgmtWrapper *pWrapper, const SRpcMsg *pRsp);
|
int64_t numOfBatchInsertReqs;
|
||||||
void dndRegisterBrokenLinkArg(SMgmtWrapper *pWrapper, SRpcMsg *pMsg);
|
int64_t numOfBatchInsertSuccessReqs;
|
||||||
SMsgCb dndCreateMsgcb(SMgmtWrapper *pWrapper);
|
} SVnodesStat;
|
||||||
|
|
||||||
|
void vmMonitorVnodeLoads(SMgmtWrapper *pWrapper, SArray *pLoads);
|
||||||
|
int32_t vmMonitorTfsInfo(SMgmtWrapper *pWrapper, SMonDiskInfo *pInfo);
|
||||||
|
void vmMonitorVnodeReqs(SMgmtWrapper *pWrapper, SMonDnodeInfo *pInfo);
|
||||||
|
int32_t mmMonitorMnodeInfo(SMgmtWrapper *pWrapper, SMonClusterInfo *pClusterInfo, SMonVgroupInfo *pVgroupInfo,
|
||||||
|
SMonGrantInfo *pGrantInfo);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /*_TD_DND_H_*/
|
#endif /*_TD_DND_INT_H_*/
|
|
@ -16,7 +16,7 @@
|
||||||
#ifndef _TD_DND_MNODE_INT_H_
|
#ifndef _TD_DND_MNODE_INT_H_
|
||||||
#define _TD_DND_MNODE_INT_H_
|
#define _TD_DND_MNODE_INT_H_
|
||||||
|
|
||||||
#include "mm.h"
|
#include "dndInt.h"
|
||||||
#include "mnode.h"
|
#include "mnode.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -46,8 +46,8 @@ int32_t mmOpenFromMsg(SMgmtWrapper *pWrapper, SDCreateMnodeReq *pReq);
|
||||||
int32_t mmDrop(SMgmtWrapper *pWrapper);
|
int32_t mmDrop(SMgmtWrapper *pWrapper);
|
||||||
int32_t mmAlter(SMnodeMgmt *pMgmt, SDAlterMnodeReq *pReq);
|
int32_t mmAlter(SMnodeMgmt *pMgmt, SDAlterMnodeReq *pReq);
|
||||||
|
|
||||||
// mmMsg.c
|
// mmHandle.c
|
||||||
void mmInitMsgHandles(SMgmtWrapper *pWrapper);
|
void mmInitMsgHandle(SMgmtWrapper *pWrapper);
|
||||||
int32_t mmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
int32_t mmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
||||||
int32_t mmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
int32_t mmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
||||||
int32_t mmProcessAlterReq(SMnodeMgmt *pMgmt, SNodeMsg *pMsg);
|
int32_t mmProcessAlterReq(SMnodeMgmt *pMgmt, SNodeMsg *pMsg);
|
|
@ -16,7 +16,7 @@
|
||||||
#ifndef _TD_DND_QNODE_INT_H_
|
#ifndef _TD_DND_QNODE_INT_H_
|
||||||
#define _TD_DND_QNODE_INT_H_
|
#define _TD_DND_QNODE_INT_H_
|
||||||
|
|
||||||
#include "qm.h"
|
#include "dndInt.h"
|
||||||
#include "qnode.h"
|
#include "qnode.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -36,8 +36,8 @@ typedef struct SQnodeMgmt {
|
||||||
int32_t qmOpen(SMgmtWrapper *pWrapper);
|
int32_t qmOpen(SMgmtWrapper *pWrapper);
|
||||||
int32_t qmDrop(SMgmtWrapper *pWrapper);
|
int32_t qmDrop(SMgmtWrapper *pWrapper);
|
||||||
|
|
||||||
// qmMsg.c
|
// qmHandle.c
|
||||||
void qmInitMsgHandles(SMgmtWrapper *pWrapper);
|
void qmInitMsgHandle(SMgmtWrapper *pWrapper);
|
||||||
int32_t qmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
int32_t qmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
||||||
int32_t qmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
int32_t qmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#ifndef _TD_DND_SNODE_INT_H_
|
#ifndef _TD_DND_SNODE_INT_H_
|
||||||
#define _TD_DND_SNODE_INT_H_
|
#define _TD_DND_SNODE_INT_H_
|
||||||
|
|
||||||
#include "sm.h"
|
#include "dndInt.h"
|
||||||
#include "snode.h"
|
#include "snode.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -38,8 +38,8 @@ typedef struct SSnodeMgmt {
|
||||||
int32_t smOpen(SMgmtWrapper *pWrapper);
|
int32_t smOpen(SMgmtWrapper *pWrapper);
|
||||||
int32_t smDrop(SMgmtWrapper *pWrapper);
|
int32_t smDrop(SMgmtWrapper *pWrapper);
|
||||||
|
|
||||||
// smMsg.c
|
// smHandle.c
|
||||||
void smInitMsgHandles(SMgmtWrapper *pWrapper);
|
void smInitMsgHandle(SMgmtWrapper *pWrapper);
|
||||||
int32_t smProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
int32_t smProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
||||||
int32_t smProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
int32_t smProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg);
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#define _TD_DND_VNODES_INT_H_
|
#define _TD_DND_VNODES_INT_H_
|
||||||
|
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "vm.h"
|
#include "dndInt.h"
|
||||||
#include "vnode.h"
|
#include "vnode.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -84,8 +84,8 @@ void vmReleaseVnode(SVnodesMgmt *pMgmt, SVnodeObj *pVnode);
|
||||||
int32_t vmOpenVnode(SVnodesMgmt *pMgmt, SWrapperCfg *pCfg, SVnode *pImpl);
|
int32_t vmOpenVnode(SVnodesMgmt *pMgmt, SWrapperCfg *pCfg, SVnode *pImpl);
|
||||||
void vmCloseVnode(SVnodesMgmt *pMgmt, SVnodeObj *pVnode);
|
void vmCloseVnode(SVnodesMgmt *pMgmt, SVnodeObj *pVnode);
|
||||||
|
|
||||||
// vmMsg.c
|
// vmHandle.c
|
||||||
void vmInitMsgHandles(SMgmtWrapper *pWrapper);
|
void vmInitMsgHandle(SMgmtWrapper *pWrapper);
|
||||||
int32_t vmProcessCreateVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pReq);
|
int32_t vmProcessCreateVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pReq);
|
||||||
int32_t vmProcessAlterVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pReq);
|
int32_t vmProcessAlterVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pReq);
|
||||||
int32_t vmProcessDropVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pReq);
|
int32_t vmProcessDropVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pReq);
|
|
@ -15,6 +15,48 @@
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "dndInt.h"
|
#include "dndInt.h"
|
||||||
|
#include "wal.h"
|
||||||
|
|
||||||
|
static int8_t once = DND_ENV_INIT;
|
||||||
|
|
||||||
|
int32_t dndInit() {
|
||||||
|
dDebug("start to init dnode env");
|
||||||
|
if (atomic_val_compare_exchange_8(&once, DND_ENV_INIT, DND_ENV_READY) != DND_ENV_INIT) {
|
||||||
|
terrno = TSDB_CODE_REPEAT_INIT;
|
||||||
|
dError("failed to init dnode env since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosIgnSIGPIPE();
|
||||||
|
taosBlockSIGPIPE();
|
||||||
|
taosResolveCRC();
|
||||||
|
|
||||||
|
SMonCfg monCfg = {0};
|
||||||
|
monCfg.maxLogs = tsMonitorMaxLogs;
|
||||||
|
monCfg.port = tsMonitorPort;
|
||||||
|
monCfg.server = tsMonitorFqdn;
|
||||||
|
monCfg.comp = tsMonitorComp;
|
||||||
|
if (monInit(&monCfg) != 0) {
|
||||||
|
dError("failed to init monitor since %s", terrstr());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dInfo("dnode env is initialized");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dndCleanup() {
|
||||||
|
dDebug("start to cleanup dnode env");
|
||||||
|
if (atomic_val_compare_exchange_8(&once, DND_ENV_READY, DND_ENV_CLEANUP) != DND_ENV_READY) {
|
||||||
|
dError("dnode env is already cleaned up");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
monCleanup();
|
||||||
|
walCleanUp();
|
||||||
|
taosStopCacheRefreshWorker();
|
||||||
|
dInfo("dnode env is cleaned up");
|
||||||
|
}
|
||||||
|
|
||||||
const char *dndStatStr(EDndStatus status) {
|
const char *dndStatStr(EDndStatus status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
@ -25,7 +67,7 @@ const char *dndStatStr(EDndStatus status) {
|
||||||
case DND_STAT_STOPPED:
|
case DND_STAT_STOPPED:
|
||||||
return "stopped";
|
return "stopped";
|
||||||
default:
|
default:
|
||||||
return "unknown";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,53 +65,6 @@ void dndCloseNode(SMgmtWrapper *pWrapper) {
|
||||||
dDebug("node:%s, mgmt has been closed", pWrapper->name);
|
dDebug("node:%s, mgmt has been closed", pWrapper->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dndConsumeChildQueue(SMgmtWrapper *pWrapper, SNodeMsg *pMsg, int16_t msgLen, void *pCont, int32_t contLen,
|
|
||||||
ProcFuncType ftype) {
|
|
||||||
SRpcMsg *pRpc = &pMsg->rpcMsg;
|
|
||||||
pRpc->pCont = pCont;
|
|
||||||
dTrace("msg:%p, get from child queue, handle:%p app:%p", pMsg, pRpc->handle, pRpc->ahandle);
|
|
||||||
|
|
||||||
NodeMsgFp msgFp = pWrapper->msgFps[TMSG_INDEX(pRpc->msgType)];
|
|
||||||
int32_t code = (*msgFp)(pWrapper, pMsg);
|
|
||||||
|
|
||||||
if (code != 0) {
|
|
||||||
dError("msg:%p, failed to process since code:0x%04x:%s", pMsg, code & 0XFFFF, tstrerror(code));
|
|
||||||
if (pRpc->msgType & 1U) {
|
|
||||||
SRpcMsg rsp = {.handle = pRpc->handle, .ahandle = pRpc->ahandle, .code = terrno};
|
|
||||||
dndSendRsp(pWrapper, &rsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
dTrace("msg:%p, is freed", pMsg);
|
|
||||||
taosFreeQitem(pMsg);
|
|
||||||
rpcFreeCont(pCont);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dndConsumeParentQueue(SMgmtWrapper *pWrapper, SRpcMsg *pMsg, int16_t msgLen, void *pCont, int32_t contLen,
|
|
||||||
ProcFuncType ftype) {
|
|
||||||
pMsg->pCont = pCont;
|
|
||||||
dTrace("msg:%p, get from parent queue, ftype:%d handle:%p, app:%p", pMsg, ftype, pMsg->handle, pMsg->ahandle);
|
|
||||||
|
|
||||||
switch (ftype) {
|
|
||||||
case PROC_REGIST:
|
|
||||||
rpcRegisterBrokenLinkArg(pMsg);
|
|
||||||
break;
|
|
||||||
case PROC_RELEASE:
|
|
||||||
rpcReleaseHandle(pMsg->handle, (int8_t)pMsg->code);
|
|
||||||
rpcFreeCont(pCont);
|
|
||||||
break;
|
|
||||||
case PROC_REQ:
|
|
||||||
dndSendReqToMnode(pWrapper, pMsg);
|
|
||||||
// dndSendReq(pWrapper, (const SEpSet *)((char *)pMsg + sizeof(SRpcMsg)), pMsg);
|
|
||||||
break;
|
|
||||||
case PROC_RSP:
|
|
||||||
dndSendRpcRsp(pWrapper, pMsg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
taosMemoryFree(pMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dndNewProc(SMgmtWrapper *pWrapper, ENodeType n) {
|
static int32_t dndNewProc(SMgmtWrapper *pWrapper, ENodeType n) {
|
||||||
char tstr[8] = {0};
|
char tstr[8] = {0};
|
||||||
|
@ -135,21 +88,9 @@ static int32_t dndNewProc(SMgmtWrapper *pWrapper, ENodeType n) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SProcCfg dndGenProcCfg(SMgmtWrapper *pWrapper) {
|
static void dndProcessProcHandle(void *handle) {
|
||||||
SProcCfg cfg = {.childConsumeFp = (ProcConsumeFp)dndConsumeChildQueue,
|
SRpcMsg rpcMsg = {.handle = handle, .code = TSDB_CODE_DND_OFFLINE};
|
||||||
.childMallocHeadFp = (ProcMallocFp)taosAllocateQitem,
|
rpcSendResponse(&rpcMsg);
|
||||||
.childFreeHeadFp = (ProcFreeFp)taosFreeQitem,
|
|
||||||
.childMallocBodyFp = (ProcMallocFp)rpcMallocCont,
|
|
||||||
.childFreeBodyFp = (ProcFreeFp)rpcFreeCont,
|
|
||||||
.parentConsumeFp = (ProcConsumeFp)dndConsumeParentQueue,
|
|
||||||
.parentMallocHeadFp = (ProcMallocFp)taosMemoryMalloc,
|
|
||||||
.parentFreeHeadFp = (ProcFreeFp)taosMemoryFree,
|
|
||||||
.parentMallocBodyFp = (ProcMallocFp)rpcMallocCont,
|
|
||||||
.parentFreeBodyFp = (ProcFreeFp)rpcFreeCont,
|
|
||||||
.shm = pWrapper->shm,
|
|
||||||
.pParent = pWrapper,
|
|
||||||
.name = pWrapper->name};
|
|
||||||
return cfg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t dndRunInSingleProcess(SDnode *pDnode) {
|
static int32_t dndRunInSingleProcess(SDnode *pDnode) {
|
||||||
|
@ -283,6 +224,7 @@ static int32_t dndRunInParentProcess(SDnode *pDnode) {
|
||||||
|
|
||||||
if (pWrapper->procId <= 0 || !taosProcExist(pWrapper->procId)) {
|
if (pWrapper->procId <= 0 || !taosProcExist(pWrapper->procId)) {
|
||||||
dInfo("node:%s, process:%d is killed and needs to be restarted", pWrapper->name, pWrapper->procId);
|
dInfo("node:%s, process:%d is killed and needs to be restarted", pWrapper->name, pWrapper->procId);
|
||||||
|
taosProcCloseHandles(pWrapper->pProc, dndProcessProcHandle);
|
||||||
dndNewProc(pWrapper, n);
|
dndNewProc(pWrapper, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -82,12 +82,12 @@ SDnode *dndCreate(const SDnodeOpt *pOption) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dndSetStatus(pDnode, DND_STAT_INIT);
|
dndSetStatus(pDnode, DND_STAT_INIT);
|
||||||
dmGetMgmtFp(&pDnode->wrappers[DNODE]);
|
dmSetMgmtFp(&pDnode->wrappers[DNODE]);
|
||||||
mmGetMgmtFp(&pDnode->wrappers[MNODE]);
|
mmSetMgmtFp(&pDnode->wrappers[MNODE]);
|
||||||
vmGetMgmtFp(&pDnode->wrappers[VNODES]);
|
vmSetMgmtFp(&pDnode->wrappers[VNODES]);
|
||||||
qmGetMgmtFp(&pDnode->wrappers[QNODE]);
|
qmSetMgmtFp(&pDnode->wrappers[QNODE]);
|
||||||
smGetMgmtFp(&pDnode->wrappers[SNODE]);
|
smSetMgmtFp(&pDnode->wrappers[SNODE]);
|
||||||
bmGetMgmtFp(&pDnode->wrappers[BNODE]);
|
bmSetMgmtFp(&pDnode->wrappers[BNODE]);
|
||||||
|
|
||||||
for (ENodeType n = 0; n < NODE_MAX; ++n) {
|
for (ENodeType n = 0; n < NODE_MAX; ++n) {
|
||||||
SMgmtWrapper *pWrapper = &pDnode->wrappers[n];
|
SMgmtWrapper *pWrapper = &pDnode->wrappers[n];
|
||||||
|
@ -95,6 +95,7 @@ SDnode *dndCreate(const SDnodeOpt *pOption) {
|
||||||
pWrapper->path = strdup(path);
|
pWrapper->path = strdup(path);
|
||||||
pWrapper->shm.id = -1;
|
pWrapper->shm.id = -1;
|
||||||
pWrapper->pDnode = pDnode;
|
pWrapper->pDnode = pDnode;
|
||||||
|
pWrapper->ntype = n;
|
||||||
if (pWrapper->path == NULL) {
|
if (pWrapper->path == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
goto _OVER;
|
goto _OVER;
|
||||||
|
@ -203,3 +204,26 @@ void dndSetStatus(SDnode *pDnode, EDndStatus status) {
|
||||||
pDnode->status = status;
|
pDnode->status = status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dndReportStartup(SDnode *pDnode, const char *pName, const char *pDesc) {
|
||||||
|
SStartupReq *pStartup = &pDnode->startup;
|
||||||
|
tstrncpy(pStartup->name, pName, TSDB_STEP_NAME_LEN);
|
||||||
|
tstrncpy(pStartup->desc, pDesc, TSDB_STEP_DESC_LEN);
|
||||||
|
pStartup->finished = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndGetStartup(SDnode *pDnode, SStartupReq *pStartup) {
|
||||||
|
memcpy(pStartup, &pDnode->startup, sizeof(SStartupReq));
|
||||||
|
pStartup->finished = (dndGetStatus(pDnode) == DND_STAT_RUNNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dndProcessStartupReq(SDnode *pDnode, SRpcMsg *pReq) {
|
||||||
|
dDebug("startup req is received");
|
||||||
|
SStartupReq *pStartup = rpcMallocCont(sizeof(SStartupReq));
|
||||||
|
dndGetStartup(pDnode, pStartup);
|
||||||
|
|
||||||
|
dDebug("startup req is sent, step:%s desc:%s finished:%d", pStartup->name, pStartup->desc, pStartup->finished);
|
||||||
|
SRpcMsg rpcRsp = {
|
||||||
|
.handle = pReq->handle, .pCont = pStartup, .contLen = sizeof(SStartupReq), .ahandle = pReq->ahandle};
|
||||||
|
rpcSendResponse(&rpcRsp);
|
||||||
|
}
|
|
@ -0,0 +1,490 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
|
#include "dndInt.h"
|
||||||
|
|
||||||
|
#define INTERNAL_USER "_dnd"
|
||||||
|
#define INTERNAL_CKEY "_key"
|
||||||
|
#define INTERNAL_SECRET "_pwd"
|
||||||
|
|
||||||
|
static void dndUpdateMnodeEpSet(SDnode *pDnode, SEpSet *pEpSet) {
|
||||||
|
SMgmtWrapper *pWrapper = &pDnode->wrappers[DNODE];
|
||||||
|
dmUpdateMnodeEpSet(pWrapper->pMgmt, pEpSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline NodeMsgFp dndGetMsgFp(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) {
|
||||||
|
NodeMsgFp msgFp = pWrapper->msgFps[TMSG_INDEX(pRpc->msgType)];
|
||||||
|
if (msgFp == NULL) {
|
||||||
|
terrno = TSDB_CODE_MSG_NOT_PROCESSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return msgFp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int32_t dndBuildMsg(SNodeMsg *pMsg, SRpcMsg *pRpc) {
|
||||||
|
SRpcConnInfo connInfo = {0};
|
||||||
|
if ((pRpc->msgType & 1U) && rpcGetConnInfo(pRpc->handle, &connInfo) != 0) {
|
||||||
|
terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
|
||||||
|
dError("failed to build msg since %s, app:%p handle:%p", terrstr(), pRpc->ahandle, pRpc->handle);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pMsg->user, connInfo.user, TSDB_USER_LEN);
|
||||||
|
pMsg->clientIp = connInfo.clientIp;
|
||||||
|
pMsg->clientPort = connInfo.clientPort;
|
||||||
|
memcpy(&pMsg->rpcMsg, pRpc, sizeof(SRpcMsg));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndProcessRpcMsg(SMgmtWrapper *pWrapper, SRpcMsg *pRpc, SEpSet *pEpSet) {
|
||||||
|
int32_t code = -1;
|
||||||
|
SNodeMsg *pMsg = NULL;
|
||||||
|
NodeMsgFp msgFp = NULL;
|
||||||
|
|
||||||
|
if (pEpSet && pEpSet->numOfEps > 0 && pRpc->msgType == TDMT_MND_STATUS_RSP) {
|
||||||
|
dndUpdateMnodeEpSet(pWrapper->pDnode, pEpSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dndMarkWrapper(pWrapper) != 0) goto _OVER;
|
||||||
|
if ((msgFp = dndGetMsgFp(pWrapper, pRpc)) == NULL) goto _OVER;
|
||||||
|
if ((pMsg = taosAllocateQitem(sizeof(SNodeMsg))) == NULL) goto _OVER;
|
||||||
|
if (dndBuildMsg(pMsg, pRpc) != 0) goto _OVER;
|
||||||
|
|
||||||
|
if (pWrapper->procType == PROC_SINGLE) {
|
||||||
|
dTrace("msg:%p, is created, handle:%p user:%s", pMsg, pRpc->handle, pMsg->user);
|
||||||
|
code = (*msgFp)(pWrapper, pMsg);
|
||||||
|
} else if (pWrapper->procType == PROC_PARENT) {
|
||||||
|
dTrace("msg:%p, is created and put into child queue, handle:%p user:%s", pMsg, pRpc->handle, pMsg->user);
|
||||||
|
code = taosProcPutToChildQ(pWrapper->pProc, pMsg, sizeof(SNodeMsg), pRpc->pCont, pRpc->contLen, pRpc->handle,
|
||||||
|
PROC_REQ);
|
||||||
|
} else {
|
||||||
|
dTrace("msg:%p, should not processed in child process, handle:%p user:%s", pMsg, pRpc->handle, pMsg->user);
|
||||||
|
ASSERT(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_OVER:
|
||||||
|
if (code == 0) {
|
||||||
|
if (pWrapper->procType == PROC_PARENT) {
|
||||||
|
dTrace("msg:%p, is freed in parent process", pMsg);
|
||||||
|
taosFreeQitem(pMsg);
|
||||||
|
rpcFreeCont(pRpc->pCont);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dError("msg:%p, failed to process since 0x%04x:%s", pMsg, code & 0XFFFF, terrstr());
|
||||||
|
if (pRpc->msgType & 1U) {
|
||||||
|
SRpcMsg rsp = {.handle = pRpc->handle, .ahandle = pRpc->ahandle, .code = terrno};
|
||||||
|
tmsgSendRsp(&rsp);
|
||||||
|
}
|
||||||
|
dTrace("msg:%p, is freed", pMsg);
|
||||||
|
taosFreeQitem(pMsg);
|
||||||
|
rpcFreeCont(pRpc->pCont);
|
||||||
|
}
|
||||||
|
|
||||||
|
dndReleaseWrapper(pWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndProcessMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
||||||
|
STransMgmt *pMgmt = &pDnode->trans;
|
||||||
|
tmsg_t msgType = pMsg->msgType;
|
||||||
|
bool isReq = msgType & 1u;
|
||||||
|
SMsgHandle *pHandle = &pMgmt->msgHandles[TMSG_INDEX(msgType)];
|
||||||
|
SMgmtWrapper *pWrapper = pHandle->pWrapper;
|
||||||
|
|
||||||
|
if (msgType == TDMT_DND_NETWORK_TEST) {
|
||||||
|
dTrace("network test req will be processed, handle:%p, app:%p", pMsg->handle, pMsg->ahandle);
|
||||||
|
dndProcessStartupReq(pDnode, pMsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dndGetStatus(pDnode) != DND_STAT_RUNNING) {
|
||||||
|
dError("msg:%s ignored since dnode not running, handle:%p app:%p", TMSG_INFO(msgType), pMsg->handle, pMsg->ahandle);
|
||||||
|
if (isReq) {
|
||||||
|
SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_APP_NOT_READY, .ahandle = pMsg->ahandle};
|
||||||
|
rpcSendResponse(&rspMsg);
|
||||||
|
}
|
||||||
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isReq && pMsg->pCont == NULL) {
|
||||||
|
dError("req:%s not processed since its empty, handle:%p app:%p", TMSG_INFO(msgType), pMsg->handle, pMsg->ahandle);
|
||||||
|
SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_DND_INVALID_MSG_LEN, .ahandle = pMsg->ahandle};
|
||||||
|
rpcSendResponse(&rspMsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pWrapper == NULL) {
|
||||||
|
dError("msg:%s not processed since no handle, handle:%p app:%p", TMSG_INFO(msgType), pMsg->handle, pMsg->ahandle);
|
||||||
|
if (isReq) {
|
||||||
|
SRpcMsg rspMsg = {.handle = pMsg->handle, .code = TSDB_CODE_MSG_NOT_PROCESSED, .ahandle = pMsg->ahandle};
|
||||||
|
rpcSendResponse(&rspMsg);
|
||||||
|
}
|
||||||
|
rpcFreeCont(pMsg->pCont);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pHandle->pMndWrapper != NULL || pHandle->pQndWrapper != NULL) {
|
||||||
|
SMsgHead *pHead = pMsg->pCont;
|
||||||
|
int32_t vgId = ntohl(pHead->vgId);
|
||||||
|
if (vgId == QNODE_HANDLE) {
|
||||||
|
pWrapper = pHandle->pQndWrapper;
|
||||||
|
} else if (vgId == MNODE_HANDLE) {
|
||||||
|
pWrapper = pHandle->pMndWrapper;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dTrace("msg:%s will be processed by %s, app:%p", TMSG_INFO(msgType), pWrapper->name, pMsg->ahandle);
|
||||||
|
dndProcessRpcMsg(pWrapper, pMsg, pEpSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndInitClient(SDnode *pDnode) {
|
||||||
|
STransMgmt *pMgmt = &pDnode->trans;
|
||||||
|
|
||||||
|
SRpcInit rpcInit;
|
||||||
|
memset(&rpcInit, 0, sizeof(rpcInit));
|
||||||
|
rpcInit.label = "DND";
|
||||||
|
rpcInit.numOfThreads = 1;
|
||||||
|
rpcInit.cfp = (RpcCfp)dndProcessMsg;
|
||||||
|
rpcInit.sessions = 1024;
|
||||||
|
rpcInit.connType = TAOS_CONN_CLIENT;
|
||||||
|
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
||||||
|
rpcInit.user = INTERNAL_USER;
|
||||||
|
rpcInit.ckey = INTERNAL_CKEY;
|
||||||
|
rpcInit.spi = 1;
|
||||||
|
rpcInit.parent = pDnode;
|
||||||
|
|
||||||
|
char pass[TSDB_PASSWORD_LEN + 1] = {0};
|
||||||
|
taosEncryptPass_c((uint8_t *)(INTERNAL_SECRET), strlen(INTERNAL_SECRET), pass);
|
||||||
|
rpcInit.secret = pass;
|
||||||
|
|
||||||
|
pMgmt->clientRpc = rpcOpen(&rpcInit);
|
||||||
|
if (pMgmt->clientRpc == NULL) {
|
||||||
|
dError("failed to init dnode rpc client");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dDebug("dnode rpc client is initialized");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndCleanupClient(SDnode *pDnode) {
|
||||||
|
STransMgmt *pMgmt = &pDnode->trans;
|
||||||
|
if (pMgmt->clientRpc) {
|
||||||
|
rpcClose(pMgmt->clientRpc);
|
||||||
|
pMgmt->clientRpc = NULL;
|
||||||
|
dDebug("dnode rpc client is closed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void dndSendMsgToMnodeRecv(SDnode *pDnode, SRpcMsg *pReq, SRpcMsg *pRsp) {
|
||||||
|
SEpSet epSet = {0};
|
||||||
|
SMgmtWrapper *pWrapper = &pDnode->wrappers[DNODE];
|
||||||
|
dmGetMnodeEpSet(pWrapper->pMgmt, &epSet);
|
||||||
|
rpcSendRecv(pDnode->trans.clientRpc, &epSet, pReq, pRsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int32_t dndGetHideUserAuth(SDnode *pDnode, char *user, char *spi, char *encrypt, char *secret,
|
||||||
|
char *ckey) {
|
||||||
|
int32_t code = 0;
|
||||||
|
char pass[TSDB_PASSWORD_LEN + 1] = {0};
|
||||||
|
|
||||||
|
if (strcmp(user, INTERNAL_USER) == 0) {
|
||||||
|
taosEncryptPass_c((uint8_t *)(INTERNAL_SECRET), strlen(INTERNAL_SECRET), pass);
|
||||||
|
} else if (strcmp(user, TSDB_NETTEST_USER) == 0) {
|
||||||
|
taosEncryptPass_c((uint8_t *)(TSDB_NETTEST_USER), strlen(TSDB_NETTEST_USER), pass);
|
||||||
|
} else {
|
||||||
|
code = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code == 0) {
|
||||||
|
memcpy(secret, pass, TSDB_PASSWORD_LEN);
|
||||||
|
*spi = 1;
|
||||||
|
*encrypt = 0;
|
||||||
|
*ckey = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndRetrieveUserAuthInfo(SDnode *pDnode, char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
||||||
|
if (dndGetHideUserAuth(pDnode, user, spi, encrypt, secret, ckey) == 0) {
|
||||||
|
dTrace("user:%s, get auth from mnode, spi:%d encrypt:%d", user, *spi, *encrypt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SAuthReq authReq = {0};
|
||||||
|
tstrncpy(authReq.user, user, TSDB_USER_LEN);
|
||||||
|
int32_t contLen = tSerializeSAuthReq(NULL, 0, &authReq);
|
||||||
|
void *pReq = rpcMallocCont(contLen);
|
||||||
|
tSerializeSAuthReq(pReq, contLen, &authReq);
|
||||||
|
|
||||||
|
SRpcMsg rpcMsg = {.pCont = pReq, .contLen = contLen, .msgType = TDMT_MND_AUTH, .ahandle = (void *)9528};
|
||||||
|
SRpcMsg rpcRsp = {0};
|
||||||
|
dTrace("user:%s, send user auth req to other mnodes, spi:%d encrypt:%d", user, authReq.spi, authReq.encrypt);
|
||||||
|
dndSendMsgToMnodeRecv(pDnode, &rpcMsg, &rpcRsp);
|
||||||
|
|
||||||
|
if (rpcRsp.code != 0) {
|
||||||
|
terrno = rpcRsp.code;
|
||||||
|
dError("user:%s, failed to get user auth from other mnodes since %s", user, terrstr());
|
||||||
|
} else {
|
||||||
|
SAuthRsp authRsp = {0};
|
||||||
|
tDeserializeSAuthReq(rpcRsp.pCont, rpcRsp.contLen, &authRsp);
|
||||||
|
memcpy(secret, authRsp.secret, TSDB_PASSWORD_LEN);
|
||||||
|
memcpy(ckey, authRsp.ckey, TSDB_PASSWORD_LEN);
|
||||||
|
*spi = authRsp.spi;
|
||||||
|
*encrypt = authRsp.encrypt;
|
||||||
|
dTrace("user:%s, success to get user auth from other mnodes, spi:%d encrypt:%d", user, authRsp.spi,
|
||||||
|
authRsp.encrypt);
|
||||||
|
}
|
||||||
|
|
||||||
|
rpcFreeCont(rpcRsp.pCont);
|
||||||
|
return rpcRsp.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndInitServer(SDnode *pDnode) {
|
||||||
|
STransMgmt *pMgmt = &pDnode->trans;
|
||||||
|
|
||||||
|
int32_t numOfThreads = (int32_t)((tsNumOfCores * tsNumOfThreadsPerCore) / 2.0);
|
||||||
|
if (numOfThreads < 1) {
|
||||||
|
numOfThreads = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRpcInit rpcInit;
|
||||||
|
memset(&rpcInit, 0, sizeof(rpcInit));
|
||||||
|
rpcInit.localPort = pDnode->serverPort;
|
||||||
|
rpcInit.label = "DND";
|
||||||
|
rpcInit.numOfThreads = numOfThreads;
|
||||||
|
rpcInit.cfp = (RpcCfp)dndProcessMsg;
|
||||||
|
rpcInit.sessions = tsMaxShellConns;
|
||||||
|
rpcInit.connType = TAOS_CONN_SERVER;
|
||||||
|
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
||||||
|
rpcInit.afp = (RpcAfp)dndRetrieveUserAuthInfo;
|
||||||
|
rpcInit.parent = pDnode;
|
||||||
|
|
||||||
|
pMgmt->serverRpc = rpcOpen(&rpcInit);
|
||||||
|
if (pMgmt->serverRpc == NULL) {
|
||||||
|
dError("failed to init dnode rpc server");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dDebug("dnode rpc server is initialized");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndCleanupServer(SDnode *pDnode) {
|
||||||
|
STransMgmt *pMgmt = &pDnode->trans;
|
||||||
|
if (pMgmt->serverRpc) {
|
||||||
|
rpcClose(pMgmt->serverRpc);
|
||||||
|
pMgmt->serverRpc = NULL;
|
||||||
|
dDebug("dnode rpc server is closed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t dndInitTrans(SDnode *pDnode) {
|
||||||
|
if (dndInitServer(pDnode) != 0) return -1;
|
||||||
|
if (dndInitClient(pDnode) != 0) return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dndCleanupTrans(SDnode *pDnode) {
|
||||||
|
dndCleanupServer(pDnode);
|
||||||
|
dndCleanupClient(pDnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t dndInitMsgHandle(SDnode *pDnode) {
|
||||||
|
STransMgmt *pMgmt = &pDnode->trans;
|
||||||
|
|
||||||
|
for (ENodeType n = 0; n < NODE_MAX; ++n) {
|
||||||
|
SMgmtWrapper *pWrapper = &pDnode->wrappers[n];
|
||||||
|
|
||||||
|
for (int32_t msgIndex = 0; msgIndex < TDMT_MAX; ++msgIndex) {
|
||||||
|
NodeMsgFp msgFp = pWrapper->msgFps[msgIndex];
|
||||||
|
int8_t vgId = pWrapper->msgVgIds[msgIndex];
|
||||||
|
if (msgFp == NULL) continue;
|
||||||
|
|
||||||
|
SMsgHandle *pHandle = &pMgmt->msgHandles[msgIndex];
|
||||||
|
if (vgId == QNODE_HANDLE) {
|
||||||
|
if (pHandle->pQndWrapper != NULL) {
|
||||||
|
dError("msg:%s has multiple process nodes", tMsgInfo[msgIndex]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pHandle->pQndWrapper = pWrapper;
|
||||||
|
} else if (vgId == MNODE_HANDLE) {
|
||||||
|
if (pHandle->pMndWrapper != NULL) {
|
||||||
|
dError("msg:%s has multiple process nodes", tMsgInfo[msgIndex]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pHandle->pMndWrapper = pWrapper;
|
||||||
|
} else {
|
||||||
|
if (pHandle->pWrapper != NULL) {
|
||||||
|
dError("msg:%s has multiple process nodes", tMsgInfo[msgIndex]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pHandle->pWrapper = pWrapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndSendRpcReq(STransMgmt *pMgmt, const SEpSet *pEpSet, SRpcMsg *pReq) {
|
||||||
|
if (pMgmt->clientRpc == NULL) {
|
||||||
|
terrno = TSDB_CODE_DND_OFFLINE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpcSendRequest(pMgmt->clientRpc, pEpSet, pReq, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndSendRpcRsp(SMgmtWrapper *pWrapper, const SRpcMsg *pRsp) {
|
||||||
|
if (pRsp->code == TSDB_CODE_APP_NOT_READY) {
|
||||||
|
if (pWrapper->ntype == MNODE) {
|
||||||
|
dmSendRedirectRsp(pWrapper->pMgmt, pRsp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rpcSendResponse(pRsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t dndSendReq(SMgmtWrapper *pWrapper, const SEpSet *pEpSet, SRpcMsg *pReq) {
|
||||||
|
if (dndGetStatus(pWrapper->pDnode) != DND_STAT_RUNNING) {
|
||||||
|
terrno = TSDB_CODE_DND_OFFLINE;
|
||||||
|
dError("failed to send rpc msg since %s, handle:%p", terrstr(), pReq->handle);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pWrapper->procType != PROC_CHILD) {
|
||||||
|
return dndSendRpcReq(&pWrapper->pDnode->trans, pEpSet, pReq);
|
||||||
|
} else {
|
||||||
|
char *pHead = taosMemoryMalloc(sizeof(SRpcMsg) + sizeof(SEpSet));
|
||||||
|
if (pHead == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pHead, pReq, sizeof(SRpcMsg));
|
||||||
|
memcpy(pHead + sizeof(SRpcMsg), pEpSet, sizeof(SEpSet));
|
||||||
|
taosProcPutToParentQ(pWrapper->pProc, pHead, sizeof(SRpcMsg) + sizeof(SEpSet), pReq->pCont, pReq->contLen,
|
||||||
|
PROC_REQ);
|
||||||
|
taosMemoryFree(pHead);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndSendRsp(SMgmtWrapper *pWrapper, const SRpcMsg *pRsp) {
|
||||||
|
if (pWrapper->procType != PROC_CHILD) {
|
||||||
|
dndSendRpcRsp(pWrapper, pRsp);
|
||||||
|
} else {
|
||||||
|
taosProcPutToParentQ(pWrapper->pProc, pRsp, sizeof(SRpcMsg), pRsp->pCont, pRsp->contLen, PROC_RSP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndRegisterBrokenLinkArg(SMgmtWrapper *pWrapper, SRpcMsg *pMsg) {
|
||||||
|
if (pWrapper->procType != PROC_CHILD) {
|
||||||
|
rpcRegisterBrokenLinkArg(pMsg);
|
||||||
|
} else {
|
||||||
|
taosProcPutToParentQ(pWrapper->pProc, pMsg, sizeof(SRpcMsg), pMsg->pCont, pMsg->contLen, PROC_REGIST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndReleaseHandle(SMgmtWrapper *pWrapper, void *handle, int8_t type) {
|
||||||
|
if (pWrapper->procType != PROC_CHILD) {
|
||||||
|
rpcReleaseHandle(handle, type);
|
||||||
|
} else {
|
||||||
|
SRpcMsg msg = {.handle = handle, .code = type};
|
||||||
|
taosProcPutToParentQ(pWrapper->pProc, &msg, sizeof(SRpcMsg), NULL, 0, PROC_RELEASE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SMsgCb dndCreateMsgcb(SMgmtWrapper *pWrapper) {
|
||||||
|
SMsgCb msgCb = {
|
||||||
|
.pWrapper = pWrapper,
|
||||||
|
.sendReqFp = dndSendReq,
|
||||||
|
.sendRspFp = dndSendRsp,
|
||||||
|
.registerBrokenLinkArgFp = dndRegisterBrokenLinkArg,
|
||||||
|
.releaseHandleFp = dndReleaseHandle,
|
||||||
|
};
|
||||||
|
return msgCb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndConsumeChildQueue(SMgmtWrapper *pWrapper, SNodeMsg *pMsg, int16_t msgLen, void *pCont, int32_t contLen,
|
||||||
|
ProcFuncType ftype) {
|
||||||
|
SRpcMsg *pRpc = &pMsg->rpcMsg;
|
||||||
|
pRpc->pCont = pCont;
|
||||||
|
dTrace("msg:%p, get from child queue, handle:%p app:%p", pMsg, pRpc->handle, pRpc->ahandle);
|
||||||
|
|
||||||
|
NodeMsgFp msgFp = pWrapper->msgFps[TMSG_INDEX(pRpc->msgType)];
|
||||||
|
int32_t code = (*msgFp)(pWrapper, pMsg);
|
||||||
|
|
||||||
|
if (code != 0) {
|
||||||
|
dError("msg:%p, failed to process since code:0x%04x:%s", pMsg, code & 0XFFFF, tstrerror(code));
|
||||||
|
if (pRpc->msgType & 1U) {
|
||||||
|
SRpcMsg rsp = {.handle = pRpc->handle, .ahandle = pRpc->ahandle, .code = terrno};
|
||||||
|
dndSendRsp(pWrapper, &rsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
dTrace("msg:%p, is freed", pMsg);
|
||||||
|
taosFreeQitem(pMsg);
|
||||||
|
rpcFreeCont(pCont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dndConsumeParentQueue(SMgmtWrapper *pWrapper, SRpcMsg *pMsg, int16_t msgLen, void *pCont, int32_t contLen,
|
||||||
|
ProcFuncType ftype) {
|
||||||
|
pMsg->pCont = pCont;
|
||||||
|
dTrace("msg:%p, get from parent queue, ftype:%d handle:%p, app:%p", pMsg, ftype, pMsg->handle, pMsg->ahandle);
|
||||||
|
|
||||||
|
switch (ftype) {
|
||||||
|
case PROC_REGIST:
|
||||||
|
rpcRegisterBrokenLinkArg(pMsg);
|
||||||
|
break;
|
||||||
|
case PROC_RELEASE:
|
||||||
|
taosProcRemoveHandle(pWrapper->pProc, pMsg->handle);
|
||||||
|
rpcReleaseHandle(pMsg->handle, (int8_t)pMsg->code);
|
||||||
|
rpcFreeCont(pCont);
|
||||||
|
break;
|
||||||
|
case PROC_REQ:
|
||||||
|
dndSendRpcReq(&pWrapper->pDnode->trans, (SEpSet *)((char *)pMsg + sizeof(SRpcMsg)), pMsg);
|
||||||
|
break;
|
||||||
|
case PROC_RSP:
|
||||||
|
taosProcRemoveHandle(pWrapper->pProc, pMsg->handle);
|
||||||
|
dndSendRpcRsp(pWrapper, pMsg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
taosMemoryFree(pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
SProcCfg dndGenProcCfg(SMgmtWrapper *pWrapper) {
|
||||||
|
SProcCfg cfg = {.childConsumeFp = (ProcConsumeFp)dndConsumeChildQueue,
|
||||||
|
.childMallocHeadFp = (ProcMallocFp)taosAllocateQitem,
|
||||||
|
.childFreeHeadFp = (ProcFreeFp)taosFreeQitem,
|
||||||
|
.childMallocBodyFp = (ProcMallocFp)rpcMallocCont,
|
||||||
|
.childFreeBodyFp = (ProcFreeFp)rpcFreeCont,
|
||||||
|
.parentConsumeFp = (ProcConsumeFp)dndConsumeParentQueue,
|
||||||
|
.parentMallocHeadFp = (ProcMallocFp)taosMemoryMalloc,
|
||||||
|
.parentFreeHeadFp = (ProcFreeFp)taosMemoryFree,
|
||||||
|
.parentMallocBodyFp = (ProcMallocFp)rpcMallocCont,
|
||||||
|
.parentFreeBodyFp = (ProcFreeFp)rpcFreeCont,
|
||||||
|
.shm = pWrapper->shm,
|
||||||
|
.parent = pWrapper,
|
||||||
|
.name = pWrapper->name};
|
||||||
|
return cfg;
|
||||||
|
}
|
|
@ -1,63 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _TD_DND_INT_H_
|
|
||||||
#define _TD_DND_INT_H_
|
|
||||||
|
|
||||||
#include "dnd.h"
|
|
||||||
|
|
||||||
#include "bm.h"
|
|
||||||
#include "dm.h"
|
|
||||||
#include "mm.h"
|
|
||||||
#include "qm.h"
|
|
||||||
#include "sm.h"
|
|
||||||
#include "vm.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// dndEnv.h
|
|
||||||
int32_t dndInit();
|
|
||||||
void dndCleanup();
|
|
||||||
|
|
||||||
// dndExec.h
|
|
||||||
int32_t dndOpenNode(SMgmtWrapper *pWrapper);
|
|
||||||
void dndCloseNode(SMgmtWrapper *pWrapper);
|
|
||||||
int32_t dndRun(SDnode *pDnode);
|
|
||||||
|
|
||||||
// dndInt.c
|
|
||||||
SDnode *dndCreate(const SDnodeOpt *pOption);
|
|
||||||
void dndClose(SDnode *pDnode);
|
|
||||||
void dndHandleEvent(SDnode *pDnode, EDndEvent event);
|
|
||||||
|
|
||||||
// dndMsg.c
|
|
||||||
void dndProcessRpcMsg(SMgmtWrapper *pWrapper, SRpcMsg *pMsg, SEpSet *pEpSet);
|
|
||||||
void dndProcessStartupReq(SDnode *pDnode, SRpcMsg *pMsg);
|
|
||||||
|
|
||||||
// dndTransport.c
|
|
||||||
int32_t dndInitMsgHandle(SDnode *pDnode);
|
|
||||||
void dndSendRpcRsp(SMgmtWrapper *pWrapper, const SRpcMsg *pRsp);
|
|
||||||
|
|
||||||
// dndFile.c
|
|
||||||
TdFilePtr dndCheckRunning(const char *dataDir);
|
|
||||||
int32_t dndReadShmFile(SDnode *pDnode);
|
|
||||||
int32_t dndWriteShmFile(SDnode *pDnode);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*_TD_DND_INT_H_*/
|
|
|
@ -1,59 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
|
||||||
#include "dndInt.h"
|
|
||||||
#include "wal.h"
|
|
||||||
|
|
||||||
static int8_t once = DND_ENV_INIT;
|
|
||||||
|
|
||||||
int32_t dndInit() {
|
|
||||||
dDebug("start to init dnode env");
|
|
||||||
if (atomic_val_compare_exchange_8(&once, DND_ENV_INIT, DND_ENV_READY) != DND_ENV_INIT) {
|
|
||||||
terrno = TSDB_CODE_REPEAT_INIT;
|
|
||||||
dError("failed to init dnode env since %s", terrstr());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
taosIgnSIGPIPE();
|
|
||||||
taosBlockSIGPIPE();
|
|
||||||
taosResolveCRC();
|
|
||||||
|
|
||||||
SMonCfg monCfg = {0};
|
|
||||||
monCfg.maxLogs = tsMonitorMaxLogs;
|
|
||||||
monCfg.port = tsMonitorPort;
|
|
||||||
monCfg.server = tsMonitorFqdn;
|
|
||||||
monCfg.comp = tsMonitorComp;
|
|
||||||
if (monInit(&monCfg) != 0) {
|
|
||||||
dError("failed to init monitor since %s", terrstr());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dInfo("dnode env is initialized");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dndCleanup() {
|
|
||||||
dDebug("start to cleanup dnode env");
|
|
||||||
if (atomic_val_compare_exchange_8(&once, DND_ENV_READY, DND_ENV_CLEANUP) != DND_ENV_READY) {
|
|
||||||
dError("dnode env is already cleaned up");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
monCleanup();
|
|
||||||
walCleanUp();
|
|
||||||
taosStopCacheRefreshWorker();
|
|
||||||
dInfo("dnode env is cleaned up");
|
|
||||||
}
|
|
|
@ -1,197 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
|
||||||
#include "dndInt.h"
|
|
||||||
|
|
||||||
static void dndUpdateMnodeEpSet(SDnode *pDnode, SEpSet *pEpSet) {
|
|
||||||
SMgmtWrapper *pWrapper = dndAcquireWrapper(pDnode, DNODE);
|
|
||||||
if (pWrapper != NULL) {
|
|
||||||
dmUpdateMnodeEpSet(pWrapper->pMgmt, pEpSet);
|
|
||||||
dndReleaseWrapper(pWrapper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline NodeMsgFp dndGetMsgFp(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) {
|
|
||||||
NodeMsgFp msgFp = pWrapper->msgFps[TMSG_INDEX(pRpc->msgType)];
|
|
||||||
if (msgFp == NULL) {
|
|
||||||
terrno = TSDB_CODE_MSG_NOT_PROCESSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return msgFp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t dndBuildMsg(SNodeMsg *pMsg, SRpcMsg *pRpc) {
|
|
||||||
SRpcConnInfo connInfo = {0};
|
|
||||||
if ((pRpc->msgType & 1U) && rpcGetConnInfo(pRpc->handle, &connInfo) != 0) {
|
|
||||||
terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
|
|
||||||
dError("failed to build msg since %s, app:%p RPC:%p", terrstr(), pRpc->ahandle, pRpc->handle);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(pMsg->user, connInfo.user, TSDB_USER_LEN);
|
|
||||||
pMsg->clientIp = connInfo.clientIp;
|
|
||||||
pMsg->clientPort = connInfo.clientPort;
|
|
||||||
memcpy(&pMsg->rpcMsg, pRpc, sizeof(SRpcMsg));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dndProcessRpcMsg(SMgmtWrapper *pWrapper, SRpcMsg *pRpc, SEpSet *pEpSet) {
|
|
||||||
int32_t code = -1;
|
|
||||||
SNodeMsg *pMsg = NULL;
|
|
||||||
NodeMsgFp msgFp = NULL;
|
|
||||||
|
|
||||||
if (pEpSet && pEpSet->numOfEps > 0 && pRpc->msgType == TDMT_MND_STATUS_RSP) {
|
|
||||||
dndUpdateMnodeEpSet(pWrapper->pDnode, pEpSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dndMarkWrapper(pWrapper) != 0) goto _OVER;
|
|
||||||
if ((msgFp = dndGetMsgFp(pWrapper, pRpc)) == NULL) goto _OVER;
|
|
||||||
if ((pMsg = taosAllocateQitem(sizeof(SNodeMsg))) == NULL) goto _OVER;
|
|
||||||
if (dndBuildMsg(pMsg, pRpc) != 0) goto _OVER;
|
|
||||||
|
|
||||||
if (pWrapper->procType == PROC_SINGLE) {
|
|
||||||
dTrace("msg:%p, is created, handle:%p app:%p user:%s", pMsg, pRpc->handle, pRpc->ahandle, pMsg->user);
|
|
||||||
code = (*msgFp)(pWrapper, pMsg);
|
|
||||||
} else if (pWrapper->procType == PROC_PARENT) {
|
|
||||||
dTrace("msg:%p, is created and put into child queue, handle:%p app:%p user:%s", pMsg, pRpc->handle, pRpc->ahandle,
|
|
||||||
pMsg->user);
|
|
||||||
code = taosProcPutToChildQ(pWrapper->pProc, pMsg, sizeof(SNodeMsg), pRpc->pCont, pRpc->contLen, PROC_REQ);
|
|
||||||
} else {
|
|
||||||
dTrace("msg:%p, should not processed in child process, handle:%p app:%p user:%s", pMsg, pRpc->handle, pRpc->ahandle,
|
|
||||||
pMsg->user);
|
|
||||||
ASSERT(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
_OVER:
|
|
||||||
if (code == 0) {
|
|
||||||
if (pWrapper->procType == PROC_PARENT) {
|
|
||||||
dTrace("msg:%p, is freed in parent process", pMsg);
|
|
||||||
taosFreeQitem(pMsg);
|
|
||||||
rpcFreeCont(pRpc->pCont);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dError("msg:%p, failed to process since 0x%04x:%s", pMsg, code & 0XFFFF, terrstr());
|
|
||||||
if (pRpc->msgType & 1U) {
|
|
||||||
SRpcMsg rsp = {.handle = pRpc->handle, .ahandle = pRpc->ahandle, .code = terrno};
|
|
||||||
dndSendRsp(pWrapper, &rsp);
|
|
||||||
}
|
|
||||||
dTrace("msg:%p, is freed", pMsg);
|
|
||||||
taosFreeQitem(pMsg);
|
|
||||||
rpcFreeCont(pRpc->pCont);
|
|
||||||
}
|
|
||||||
|
|
||||||
dndReleaseWrapper(pWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dndProcessCreateNodeMsg(SDnode *pDnode, ENodeType ntype, SNodeMsg *pMsg) {
|
|
||||||
SMgmtWrapper *pWrapper = dndAcquireWrapper(pDnode, ntype);
|
|
||||||
if (pWrapper != NULL) {
|
|
||||||
dndReleaseWrapper(pWrapper);
|
|
||||||
terrno = TSDB_CODE_NODE_ALREADY_DEPLOYED;
|
|
||||||
dError("failed to create node since %s", terrstr());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pWrapper = &pDnode->wrappers[ntype];
|
|
||||||
|
|
||||||
if (taosMkDir(pWrapper->path) != 0) {
|
|
||||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
|
||||||
dError("failed to create dir:%s since %s", pWrapper->path, terrstr());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t code = (*pWrapper->fp.createMsgFp)(pWrapper, pMsg);
|
|
||||||
if (code != 0) {
|
|
||||||
dError("node:%s, failed to open since %s", pWrapper->name, terrstr());
|
|
||||||
} else {
|
|
||||||
dDebug("node:%s, has been opened", pWrapper->name);
|
|
||||||
pWrapper->deployed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dndProcessDropNodeMsg(SDnode *pDnode, ENodeType ntype, SNodeMsg *pMsg) {
|
|
||||||
SMgmtWrapper *pWrapper = dndAcquireWrapper(pDnode, ntype);
|
|
||||||
if (pWrapper == NULL) {
|
|
||||||
terrno = TSDB_CODE_NODE_NOT_DEPLOYED;
|
|
||||||
dError("failed to drop node since %s", terrstr());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
taosWLockLatch(&pWrapper->latch);
|
|
||||||
pWrapper->deployed = false;
|
|
||||||
|
|
||||||
int32_t code = (*pWrapper->fp.dropMsgFp)(pWrapper, pMsg);
|
|
||||||
if (code != 0) {
|
|
||||||
pWrapper->deployed = true;
|
|
||||||
dError("node:%s, failed to drop since %s", pWrapper->name, terrstr());
|
|
||||||
} else {
|
|
||||||
pWrapper->deployed = false;
|
|
||||||
dDebug("node:%s, has been dropped", pWrapper->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
taosWUnLockLatch(&pWrapper->latch);
|
|
||||||
dndReleaseWrapper(pWrapper);
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t dndProcessNodeMsg(SDnode *pDnode, SNodeMsg *pMsg) {
|
|
||||||
switch (pMsg->rpcMsg.msgType) {
|
|
||||||
case TDMT_DND_CREATE_MNODE:
|
|
||||||
return dndProcessCreateNodeMsg(pDnode, MNODE, pMsg);
|
|
||||||
case TDMT_DND_DROP_MNODE:
|
|
||||||
return dndProcessDropNodeMsg(pDnode, MNODE, pMsg);
|
|
||||||
case TDMT_DND_CREATE_QNODE:
|
|
||||||
return dndProcessCreateNodeMsg(pDnode, QNODE, pMsg);
|
|
||||||
case TDMT_DND_DROP_QNODE:
|
|
||||||
return dndProcessDropNodeMsg(pDnode, QNODE, pMsg);
|
|
||||||
case TDMT_DND_CREATE_SNODE:
|
|
||||||
return dndProcessCreateNodeMsg(pDnode, SNODE, pMsg);
|
|
||||||
case TDMT_DND_DROP_SNODE:
|
|
||||||
return dndProcessDropNodeMsg(pDnode, SNODE, pMsg);
|
|
||||||
case TDMT_DND_CREATE_BNODE:
|
|
||||||
return dndProcessCreateNodeMsg(pDnode, BNODE, pMsg);
|
|
||||||
case TDMT_DND_DROP_BNODE:
|
|
||||||
return dndProcessDropNodeMsg(pDnode, BNODE, pMsg);
|
|
||||||
default:
|
|
||||||
terrno = TSDB_CODE_MSG_NOT_PROCESSED;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dndReportStartup(SDnode *pDnode, const char *pName, const char *pDesc) {
|
|
||||||
SStartupReq *pStartup = &pDnode->startup;
|
|
||||||
tstrncpy(pStartup->name, pName, TSDB_STEP_NAME_LEN);
|
|
||||||
tstrncpy(pStartup->desc, pDesc, TSDB_STEP_DESC_LEN);
|
|
||||||
pStartup->finished = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dndGetStartup(SDnode *pDnode, SStartupReq *pStartup) {
|
|
||||||
memcpy(pStartup, &pDnode->startup, sizeof(SStartupReq));
|
|
||||||
pStartup->finished = (dndGetStatus(pDnode) == DND_STAT_RUNNING);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dndProcessStartupReq(SDnode *pDnode, SRpcMsg *pReq) {
|
|
||||||
dDebug("startup req is received");
|
|
||||||
SStartupReq *pStartup = rpcMallocCont(sizeof(SStartupReq));
|
|
||||||
dndGetStartup(pDnode, pStartup);
|
|
||||||
|
|
||||||
dDebug("startup req is sent, step:%s desc:%s finished:%d", pStartup->name, pStartup->desc, pStartup->finished);
|
|
||||||
SRpcMsg rpcRsp = {
|
|
||||||
.handle = pReq->handle, .pCont = pStartup, .contLen = sizeof(SStartupReq), .ahandle = pReq->ahandle};
|
|
||||||
rpcSendResponse(&rpcRsp);
|
|
||||||
}
|
|
|
@ -1,409 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
|
||||||
#include "dndInt.h"
|
|
||||||
|
|
||||||
#define INTERNAL_USER "_dnd"
|
|
||||||
#define INTERNAL_CKEY "_key"
|
|
||||||
#define INTERNAL_SECRET "_pwd"
|
|
||||||
|
|
||||||
static inline void dndProcessQMVnodeRpcMsg(SMsgHandle *pHandle, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|
||||||
SMsgHead *pHead = pMsg->pCont;
|
|
||||||
int32_t vgId = htonl(pHead->vgId);
|
|
||||||
|
|
||||||
SMgmtWrapper *pWrapper = pHandle->pWrapper;
|
|
||||||
if (vgId == QND_VGID) {
|
|
||||||
pWrapper = pHandle->pQndWrapper;
|
|
||||||
} else if (vgId == MND_VGID) {
|
|
||||||
pWrapper = pHandle->pMndWrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
dTrace("msg:%s will be processed by %s, handle:%p app:%p vgId:%d", TMSG_INFO(pMsg->msgType), pWrapper->name,
|
|
||||||
pMsg->handle, pMsg->ahandle, vgId);
|
|
||||||
dndProcessRpcMsg(pWrapper, pMsg, pEpSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dndProcessResponse(void *parent, SRpcMsg *pRsp, SEpSet *pEpSet) {
|
|
||||||
SDnode *pDnode = parent;
|
|
||||||
STransMgmt *pMgmt = &pDnode->trans;
|
|
||||||
tmsg_t msgType = pRsp->msgType;
|
|
||||||
|
|
||||||
if (dndGetStatus(pDnode) != DND_STAT_RUNNING) {
|
|
||||||
dTrace("rsp:%s ignored since dnode not running, handle:%p app:%p", TMSG_INFO(msgType), pRsp->handle, pRsp->ahandle);
|
|
||||||
rpcFreeCont(pRsp->pCont);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SMsgHandle *pHandle = &pMgmt->msgHandles[TMSG_INDEX(msgType)];
|
|
||||||
if (pHandle->pWrapper != NULL) {
|
|
||||||
if (pHandle->pMndWrapper == NULL && pHandle->pQndWrapper == NULL) {
|
|
||||||
dTrace("rsp:%s will be processed by %s, handle:%p app:%p code:0x%04x:%s", TMSG_INFO(msgType),
|
|
||||||
pHandle->pWrapper->name, pRsp->handle, pRsp->ahandle, pRsp->code & 0XFFFF, tstrerror(pRsp->code));
|
|
||||||
dndProcessRpcMsg(pHandle->pWrapper, pRsp, pEpSet);
|
|
||||||
} else {
|
|
||||||
dndProcessQMVnodeRpcMsg(pHandle, pRsp, pEpSet);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dError("rsp:%s not processed since no handle, handle:%p app:%p", TMSG_INFO(msgType), pRsp->handle, pRsp->ahandle);
|
|
||||||
rpcFreeCont(pRsp->pCont);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t dndInitClient(SDnode *pDnode) {
|
|
||||||
STransMgmt *pMgmt = &pDnode->trans;
|
|
||||||
|
|
||||||
SRpcInit rpcInit;
|
|
||||||
memset(&rpcInit, 0, sizeof(rpcInit));
|
|
||||||
rpcInit.label = "DND";
|
|
||||||
rpcInit.numOfThreads = 1;
|
|
||||||
rpcInit.cfp = dndProcessResponse;
|
|
||||||
rpcInit.sessions = 1024;
|
|
||||||
rpcInit.connType = TAOS_CONN_CLIENT;
|
|
||||||
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
|
||||||
rpcInit.user = INTERNAL_USER;
|
|
||||||
rpcInit.ckey = INTERNAL_CKEY;
|
|
||||||
rpcInit.spi = 1;
|
|
||||||
rpcInit.parent = pDnode;
|
|
||||||
|
|
||||||
char pass[TSDB_PASSWORD_LEN + 1] = {0};
|
|
||||||
taosEncryptPass_c((uint8_t *)(INTERNAL_SECRET), strlen(INTERNAL_SECRET), pass);
|
|
||||||
rpcInit.secret = pass;
|
|
||||||
|
|
||||||
pMgmt->clientRpc = rpcOpen(&rpcInit);
|
|
||||||
if (pMgmt->clientRpc == NULL) {
|
|
||||||
dError("failed to init dnode rpc client");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dDebug("dnode rpc client is initialized");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dndCleanupClient(SDnode *pDnode) {
|
|
||||||
STransMgmt *pMgmt = &pDnode->trans;
|
|
||||||
if (pMgmt->clientRpc) {
|
|
||||||
rpcClose(pMgmt->clientRpc);
|
|
||||||
pMgmt->clientRpc = NULL;
|
|
||||||
dDebug("dnode rpc client is closed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dndProcessRequest(void *param, SRpcMsg *pReq, SEpSet *pEpSet) {
|
|
||||||
SDnode *pDnode = param;
|
|
||||||
STransMgmt *pMgmt = &pDnode->trans;
|
|
||||||
tmsg_t msgType = pReq->msgType;
|
|
||||||
|
|
||||||
if (msgType == TDMT_DND_NETWORK_TEST) {
|
|
||||||
dTrace("network test req will be processed, handle:%p, app:%p", pReq->handle, pReq->ahandle);
|
|
||||||
dndProcessStartupReq(pDnode, pReq);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dndGetStatus(pDnode) != DND_STAT_RUNNING) {
|
|
||||||
dError("req:%s ignored since dnode not running, handle:%p app:%p", TMSG_INFO(msgType), pReq->handle, pReq->ahandle);
|
|
||||||
SRpcMsg rspMsg = {.handle = pReq->handle, .code = TSDB_CODE_APP_NOT_READY, .ahandle = pReq->ahandle};
|
|
||||||
rpcSendResponse(&rspMsg);
|
|
||||||
rpcFreeCont(pReq->pCont);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pReq->pCont == NULL) {
|
|
||||||
dTrace("req:%s not processed since its empty, handle:%p app:%p", TMSG_INFO(msgType), pReq->handle, pReq->ahandle);
|
|
||||||
SRpcMsg rspMsg = {.handle = pReq->handle, .code = TSDB_CODE_DND_INVALID_MSG_LEN, .ahandle = pReq->ahandle};
|
|
||||||
rpcSendResponse(&rspMsg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SMsgHandle *pHandle = &pMgmt->msgHandles[TMSG_INDEX(msgType)];
|
|
||||||
if (pHandle->pWrapper != NULL) {
|
|
||||||
if (pHandle->pMndWrapper == NULL && pHandle->pQndWrapper == NULL) {
|
|
||||||
dTrace("req:%s will be processed by %s, handle:%p app:%p", TMSG_INFO(msgType), pHandle->pWrapper->name,
|
|
||||||
pReq->handle, pReq->ahandle);
|
|
||||||
dndProcessRpcMsg(pHandle->pWrapper, pReq, pEpSet);
|
|
||||||
} else {
|
|
||||||
dndProcessQMVnodeRpcMsg(pHandle, pReq, pEpSet);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dError("req:%s not processed since no handle, handle:%p app:%p", TMSG_INFO(msgType), pReq->handle, pReq->ahandle);
|
|
||||||
SRpcMsg rspMsg = {.handle = pReq->handle, .code = TSDB_CODE_MSG_NOT_PROCESSED, .ahandle = pReq->ahandle};
|
|
||||||
rpcSendResponse(&rspMsg);
|
|
||||||
rpcFreeCont(pReq->pCont);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dndSendMsgToMnodeRecv(SDnode *pDnode, SRpcMsg *pRpcMsg, SRpcMsg *pRpcRsp) {
|
|
||||||
STransMgmt *pMgmt = &pDnode->trans;
|
|
||||||
SEpSet epSet = {0};
|
|
||||||
|
|
||||||
SMgmtWrapper *pWrapper = dndAcquireWrapper(pDnode, DNODE);
|
|
||||||
if (pWrapper != NULL) {
|
|
||||||
dmGetMnodeEpSet(pWrapper->pMgmt, &epSet);
|
|
||||||
dndReleaseWrapper(pWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
rpcSendRecv(pMgmt->clientRpc, &epSet, pRpcMsg, pRpcRsp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dndGetHideUserAuth(SDnode *pDnode, char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
|
||||||
int32_t code = 0;
|
|
||||||
char pass[TSDB_PASSWORD_LEN + 1] = {0};
|
|
||||||
|
|
||||||
if (strcmp(user, INTERNAL_USER) == 0) {
|
|
||||||
taosEncryptPass_c((uint8_t *)(INTERNAL_SECRET), strlen(INTERNAL_SECRET), pass);
|
|
||||||
} else if (strcmp(user, TSDB_NETTEST_USER) == 0) {
|
|
||||||
taosEncryptPass_c((uint8_t *)(TSDB_NETTEST_USER), strlen(TSDB_NETTEST_USER), pass);
|
|
||||||
} else {
|
|
||||||
code = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (code == 0) {
|
|
||||||
memcpy(secret, pass, TSDB_PASSWORD_LEN);
|
|
||||||
*spi = 1;
|
|
||||||
*encrypt = 0;
|
|
||||||
*ckey = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dndRetrieveUserAuthInfo(void *parent, char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
|
||||||
SDnode *pDnode = parent;
|
|
||||||
|
|
||||||
if (dndGetHideUserAuth(parent, user, spi, encrypt, secret, ckey) == 0) {
|
|
||||||
dTrace("user:%s, get auth from mnode, spi:%d encrypt:%d", user, *spi, *encrypt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SMgmtWrapper *pWrapper = dndAcquireWrapper(pDnode, MNODE);
|
|
||||||
if (pWrapper != NULL) {
|
|
||||||
if (mmGetUserAuth(pWrapper, user, spi, encrypt, secret, ckey) == 0) {
|
|
||||||
dndReleaseWrapper(pWrapper);
|
|
||||||
dTrace("user:%s, get auth from mnode, spi:%d encrypt:%d", user, *spi, *encrypt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
dndReleaseWrapper(pWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (terrno != TSDB_CODE_APP_NOT_READY) {
|
|
||||||
dTrace("failed to get user auth from mnode since %s", terrstr());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SAuthReq authReq = {0};
|
|
||||||
tstrncpy(authReq.user, user, TSDB_USER_LEN);
|
|
||||||
int32_t contLen = tSerializeSAuthReq(NULL, 0, &authReq);
|
|
||||||
void *pReq = rpcMallocCont(contLen);
|
|
||||||
tSerializeSAuthReq(pReq, contLen, &authReq);
|
|
||||||
|
|
||||||
SRpcMsg rpcMsg = {.pCont = pReq, .contLen = contLen, .msgType = TDMT_MND_AUTH, .ahandle = (void *)9528};
|
|
||||||
SRpcMsg rpcRsp = {0};
|
|
||||||
dTrace("user:%s, send user auth req to other mnodes, spi:%d encrypt:%d", user, authReq.spi, authReq.encrypt);
|
|
||||||
dndSendMsgToMnodeRecv(pDnode, &rpcMsg, &rpcRsp);
|
|
||||||
|
|
||||||
if (rpcRsp.code != 0) {
|
|
||||||
terrno = rpcRsp.code;
|
|
||||||
dError("user:%s, failed to get user auth from other mnodes since %s", user, terrstr());
|
|
||||||
} else {
|
|
||||||
SAuthRsp authRsp = {0};
|
|
||||||
tDeserializeSAuthReq(rpcRsp.pCont, rpcRsp.contLen, &authRsp);
|
|
||||||
memcpy(secret, authRsp.secret, TSDB_PASSWORD_LEN);
|
|
||||||
memcpy(ckey, authRsp.ckey, TSDB_PASSWORD_LEN);
|
|
||||||
*spi = authRsp.spi;
|
|
||||||
*encrypt = authRsp.encrypt;
|
|
||||||
dTrace("user:%s, success to get user auth from other mnodes, spi:%d encrypt:%d", user, authRsp.spi,
|
|
||||||
authRsp.encrypt);
|
|
||||||
}
|
|
||||||
|
|
||||||
rpcFreeCont(rpcRsp.pCont);
|
|
||||||
return rpcRsp.code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t dndInitServer(SDnode *pDnode) {
|
|
||||||
STransMgmt *pMgmt = &pDnode->trans;
|
|
||||||
|
|
||||||
int32_t numOfThreads = (int32_t)((tsNumOfCores * tsNumOfThreadsPerCore) / 2.0);
|
|
||||||
if (numOfThreads < 1) {
|
|
||||||
numOfThreads = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SRpcInit rpcInit;
|
|
||||||
memset(&rpcInit, 0, sizeof(rpcInit));
|
|
||||||
rpcInit.localPort = pDnode->serverPort;
|
|
||||||
rpcInit.label = "DND";
|
|
||||||
rpcInit.numOfThreads = numOfThreads;
|
|
||||||
rpcInit.cfp = dndProcessRequest;
|
|
||||||
rpcInit.sessions = tsMaxShellConns;
|
|
||||||
rpcInit.connType = TAOS_CONN_SERVER;
|
|
||||||
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
|
||||||
rpcInit.afp = dndRetrieveUserAuthInfo;
|
|
||||||
rpcInit.parent = pDnode;
|
|
||||||
|
|
||||||
pMgmt->serverRpc = rpcOpen(&rpcInit);
|
|
||||||
if (pMgmt->serverRpc == NULL) {
|
|
||||||
dError("failed to init dnode rpc server");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dDebug("dnode rpc server is initialized");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dndCleanupServer(SDnode *pDnode) {
|
|
||||||
STransMgmt *pMgmt = &pDnode->trans;
|
|
||||||
if (pMgmt->serverRpc) {
|
|
||||||
rpcClose(pMgmt->serverRpc);
|
|
||||||
pMgmt->serverRpc = NULL;
|
|
||||||
dDebug("dnode rpc server is closed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t dndInitMsgHandle(SDnode *pDnode) {
|
|
||||||
STransMgmt *pMgmt = &pDnode->trans;
|
|
||||||
|
|
||||||
for (ENodeType n = 0; n < NODE_MAX; ++n) {
|
|
||||||
SMgmtWrapper *pWrapper = &pDnode->wrappers[n];
|
|
||||||
|
|
||||||
for (int32_t msgIndex = 0; msgIndex < TDMT_MAX; ++msgIndex) {
|
|
||||||
NodeMsgFp msgFp = pWrapper->msgFps[msgIndex];
|
|
||||||
int32_t vgId = pWrapper->msgVgIds[msgIndex];
|
|
||||||
if (msgFp == NULL) continue;
|
|
||||||
|
|
||||||
// dTrace("msg:%s will be processed by %s, vgId:%d", tMsgInfo[msgIndex], pWrapper->name, vgId);
|
|
||||||
|
|
||||||
SMsgHandle *pHandle = &pMgmt->msgHandles[msgIndex];
|
|
||||||
if (vgId == QND_VGID) {
|
|
||||||
if (pHandle->pQndWrapper != NULL) {
|
|
||||||
dError("msg:%s has multiple process nodes", tMsgInfo[msgIndex]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
pHandle->pQndWrapper = pWrapper;
|
|
||||||
} else if (vgId == MND_VGID) {
|
|
||||||
if (pHandle->pMndWrapper != NULL) {
|
|
||||||
dError("msg:%s has multiple process nodes", tMsgInfo[msgIndex]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
pHandle->pMndWrapper = pWrapper;
|
|
||||||
} else {
|
|
||||||
if (pHandle->pWrapper != NULL) {
|
|
||||||
dError("msg:%s has multiple process nodes", tMsgInfo[msgIndex]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
pHandle->pWrapper = pWrapper;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t dndSendRpcReq(STransMgmt *pMgmt, const SEpSet *pEpSet, SRpcMsg *pReq) {
|
|
||||||
if (pMgmt->clientRpc == NULL) {
|
|
||||||
terrno = TSDB_CODE_DND_OFFLINE;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
rpcSendRequest(pMgmt->clientRpc, pEpSet, pReq, NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t dndSendReqToMnode(SMgmtWrapper *pWrapper, SRpcMsg *pReq) {
|
|
||||||
SDnode *pDnode = pWrapper->pDnode;
|
|
||||||
STransMgmt *pTrans = &pDnode->trans;
|
|
||||||
SEpSet epSet = {0};
|
|
||||||
|
|
||||||
SMgmtWrapper *pWrapper2 = dndAcquireWrapper(pDnode, DNODE);
|
|
||||||
if (pWrapper2 != NULL) {
|
|
||||||
dmGetMnodeEpSet(pWrapper2->pMgmt, &epSet);
|
|
||||||
dndReleaseWrapper(pWrapper2);
|
|
||||||
}
|
|
||||||
return dndSendRpcReq(pTrans, &epSet, pReq);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dndSendRpcRsp(SMgmtWrapper *pWrapper, const SRpcMsg *pRsp) {
|
|
||||||
if (pRsp->code == TSDB_CODE_APP_NOT_READY) {
|
|
||||||
SMgmtWrapper *pDnodeWrapper = dndAcquireWrapper(pWrapper->pDnode, DNODE);
|
|
||||||
if (pDnodeWrapper != NULL) {
|
|
||||||
dmSendRedirectRsp(pDnodeWrapper->pMgmt, pRsp);
|
|
||||||
dndReleaseWrapper(pDnodeWrapper);
|
|
||||||
} else {
|
|
||||||
rpcSendResponse(pRsp);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rpcSendResponse(pRsp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t dndSendReq(SMgmtWrapper *pWrapper, const SEpSet *pEpSet, SRpcMsg *pReq) {
|
|
||||||
SDnode *pDnode = pWrapper->pDnode;
|
|
||||||
if (dndGetStatus(pDnode) != DND_STAT_RUNNING) {
|
|
||||||
terrno = TSDB_CODE_DND_OFFLINE;
|
|
||||||
dError("failed to send rpc msg since %s, handle:%p", terrstr(), pReq->handle);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pWrapper->procType != PROC_CHILD) {
|
|
||||||
return dndSendRpcReq(&pDnode->trans, pEpSet, pReq);
|
|
||||||
} else {
|
|
||||||
int32_t headLen = sizeof(SRpcMsg) + sizeof(SEpSet);
|
|
||||||
char *pHead = taosMemoryMalloc(headLen);
|
|
||||||
if (pHead == NULL) {
|
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(pHead, pReq, sizeof(SRpcMsg));
|
|
||||||
memcpy(pHead + sizeof(SRpcMsg), pEpSet, sizeof(SEpSet));
|
|
||||||
|
|
||||||
taosProcPutToParentQ(pWrapper->pProc, pReq, headLen, pReq->pCont, pReq->contLen, PROC_REQ);
|
|
||||||
taosMemoryFree(pHead);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dndSendRsp(SMgmtWrapper *pWrapper, const SRpcMsg *pRsp) {
|
|
||||||
if (pWrapper->procType != PROC_CHILD) {
|
|
||||||
dndSendRpcRsp(pWrapper, pRsp);
|
|
||||||
} else {
|
|
||||||
taosProcPutToParentQ(pWrapper->pProc, pRsp, sizeof(SRpcMsg), pRsp->pCont, pRsp->contLen, PROC_RSP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dndRegisterBrokenLinkArg(SMgmtWrapper *pWrapper, SRpcMsg *pMsg) {
|
|
||||||
if (pWrapper->procType != PROC_CHILD) {
|
|
||||||
rpcRegisterBrokenLinkArg(pMsg);
|
|
||||||
} else {
|
|
||||||
taosProcPutToParentQ(pWrapper->pProc, pMsg, sizeof(SRpcMsg), pMsg->pCont, pMsg->contLen, PROC_REGIST);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dndReleaseHandle(SMgmtWrapper *pWrapper, void *handle, int8_t type) {
|
|
||||||
if (pWrapper->procType != PROC_CHILD) {
|
|
||||||
rpcReleaseHandle(handle, type);
|
|
||||||
} else {
|
|
||||||
SRpcMsg msg = {.handle = handle, .code = type};
|
|
||||||
taosProcPutToParentQ(pWrapper->pProc, &msg, sizeof(SRpcMsg), NULL, 0, PROC_RELEASE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SMsgCb dndCreateMsgcb(SMgmtWrapper *pWrapper) {
|
|
||||||
SMsgCb msgCb = {
|
|
||||||
.pWrapper = pWrapper,
|
|
||||||
.sendReqFp = dndSendReq,
|
|
||||||
.sendRspFp = dndSendRsp,
|
|
||||||
.registerBrokenLinkArgFp = dndRegisterBrokenLinkArg,
|
|
||||||
.releaseHandleFp = dndReleaseHandle,
|
|
||||||
};
|
|
||||||
return msgCb;
|
|
||||||
}
|
|
|
@ -1,35 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _TD_DND_MNODE_H_
|
|
||||||
#define _TD_DND_MNODE_H_
|
|
||||||
|
|
||||||
#include "dnd.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void mmGetMgmtFp(SMgmtWrapper *pMgmt);
|
|
||||||
|
|
||||||
int32_t mmGetUserAuth(SMgmtWrapper *pWrapper, char *user, char *spi, char *encrypt, char *secret, char *ckey);
|
|
||||||
int32_t mmMonitorMnodeInfo(SMgmtWrapper *pWrapper, SMonClusterInfo *pClusterInfo, SMonVgroupInfo *pVgroupInfo,
|
|
||||||
SMonGrantInfo *pGrantInfo);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*_TD_DND_MNODE_H_*/
|
|
|
@ -73,93 +73,93 @@ int32_t mmProcessAlterReq(SMnodeMgmt *pMgmt, SNodeMsg *pMsg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mmInitMsgHandles(SMgmtWrapper *pWrapper) {
|
void mmInitMsgHandle(SMgmtWrapper *pWrapper) {
|
||||||
// Requests handled by DNODE
|
// Requests handled by DNODE
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_MNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_MNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_ALTER_MNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_ALTER_MNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_MNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_MNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_QNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_QNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_QNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_QNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_SNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_SNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_SNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_SNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_BNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_BNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_BNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_BNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_VNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_VNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_ALTER_VNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_ALTER_VNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_VNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_VNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_SYNC_VNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_SYNC_VNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_COMPACT_VNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_COMPACT_VNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_CONFIG_DNODE_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_CONFIG_DNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
|
|
||||||
// Requests handled by MNODE
|
// Requests handled by MNODE
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CONNECT, mmProcessReadMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CONNECT, mmProcessReadMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_ACCT, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_ACCT, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_ALTER_ACCT, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_ALTER_ACCT, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_ACCT, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_ACCT, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_USER, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_USER, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_ALTER_USER, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_ALTER_USER, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_USER, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_USER, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_GET_USER_AUTH, mmProcessReadMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_GET_USER_AUTH, mmProcessReadMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_DNODE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_DNODE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CONFIG_DNODE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CONFIG_DNODE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_DNODE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_DNODE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_MNODE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_MNODE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_MNODE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_MNODE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_QNODE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_QNODE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_QNODE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_QNODE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_SNODE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_SNODE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_SNODE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_SNODE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_BNODE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_BNODE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_BNODE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_BNODE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_DB, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_DB, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_DB, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_DB, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_USE_DB, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_USE_DB, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_ALTER_DB, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_ALTER_DB, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_SYNC_DB, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_SYNC_DB, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_COMPACT_DB, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_COMPACT_DB, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_FUNC, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_FUNC, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_RETRIEVE_FUNC, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_RETRIEVE_FUNC, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_FUNC, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_FUNC, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_STB, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_STB, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_ALTER_STB, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_ALTER_STB, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_STB, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_STB, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_SMA, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_SMA, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_SMA, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_SMA, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_TABLE_META, mmProcessReadMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_TABLE_META, mmProcessReadMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_VGROUP_LIST, mmProcessReadMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_VGROUP_LIST, mmProcessReadMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_KILL_QUERY, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_KILL_QUERY, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_KILL_CONN, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_KILL_CONN, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_HEARTBEAT, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_HEARTBEAT, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_SHOW, mmProcessReadMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_SHOW, mmProcessReadMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_SHOW_RETRIEVE, mmProcessReadMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_SHOW_RETRIEVE, mmProcessReadMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_SYSTABLE_RETRIEVE, mmProcessReadMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_SYSTABLE_RETRIEVE, mmProcessReadMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_STATUS, mmProcessReadMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_STATUS, mmProcessReadMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_KILL_TRANS, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_KILL_TRANS, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_GRANT, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_GRANT, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_AUTH, mmProcessReadMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_AUTH, mmProcessReadMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_ALTER_MNODE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_ALTER_MNODE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_TOPIC, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_TOPIC, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_ALTER_TOPIC, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_ALTER_TOPIC, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_TOPIC, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_DROP_TOPIC, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_SUBSCRIBE, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_SUBSCRIBE, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_MQ_COMMIT_OFFSET, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_MQ_COMMIT_OFFSET, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_GET_SUB_EP, mmProcessReadMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_GET_SUB_EP, mmProcessReadMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_STREAM, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_MND_CREATE_STREAM, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_TASK_DEPLOY_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_TASK_DEPLOY_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
|
|
||||||
// Requests handled by VNODE
|
// Requests handled by VNODE
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_SET_CONN_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_SET_CONN_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_REB_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_REB_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_CREATE_STB_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_CREATE_STB_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_ALTER_STB_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_ALTER_STB_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_STB_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_STB_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_CREATE_SMA_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_CREATE_SMA_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_SMA_RSP, mmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_SMA_RSP, mmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
|
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY, mmProcessQueryMsg, MND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY, mmProcessQueryMsg, MNODE_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY_CONTINUE, mmProcessQueryMsg, MND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY_CONTINUE, mmProcessQueryMsg, MNODE_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_FETCH, mmProcessQueryMsg, MND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_FETCH, mmProcessQueryMsg, MNODE_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_TASK, mmProcessQueryMsg, MND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_TASK, mmProcessQueryMsg, MNODE_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY_HEARTBEAT, mmProcessQueryMsg, MND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY_HEARTBEAT, mmProcessQueryMsg, MNODE_HANDLE);
|
||||||
|
|
||||||
}
|
}
|
|
@ -227,7 +227,7 @@ static int32_t mmStart(SMgmtWrapper *pWrapper) {
|
||||||
return mndStart(pMgmt->pMnode);
|
return mndStart(pMgmt->pMnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mmGetMgmtFp(SMgmtWrapper *pWrapper) {
|
void mmSetMgmtFp(SMgmtWrapper *pWrapper) {
|
||||||
SMgmtFp mgmtFp = {0};
|
SMgmtFp mgmtFp = {0};
|
||||||
mgmtFp.openFp = mmOpen;
|
mgmtFp.openFp = mmOpen;
|
||||||
mgmtFp.closeFp = mmClose;
|
mgmtFp.closeFp = mmClose;
|
||||||
|
@ -236,19 +236,11 @@ void mmGetMgmtFp(SMgmtWrapper *pWrapper) {
|
||||||
mgmtFp.dropMsgFp = mmProcessDropReq;
|
mgmtFp.dropMsgFp = mmProcessDropReq;
|
||||||
mgmtFp.requiredFp = mmRequire;
|
mgmtFp.requiredFp = mmRequire;
|
||||||
|
|
||||||
mmInitMsgHandles(pWrapper);
|
mmInitMsgHandle(pWrapper);
|
||||||
pWrapper->name = "mnode";
|
pWrapper->name = "mnode";
|
||||||
pWrapper->fp = mgmtFp;
|
pWrapper->fp = mgmtFp;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mmGetUserAuth(SMgmtWrapper *pWrapper, char *user, char *spi, char *encrypt, char *secret, char *ckey) {
|
|
||||||
SMnodeMgmt *pMgmt = pWrapper->pMgmt;
|
|
||||||
|
|
||||||
int32_t code = mndRetriveAuth(pMgmt->pMnode, user, spi, encrypt, secret, ckey);
|
|
||||||
dTrace("user:%s, retrieve auth spi:%d encrypt:%d", user, *spi, *encrypt);
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t mmMonitorMnodeInfo(SMgmtWrapper *pWrapper, SMonClusterInfo *pClusterInfo, SMonVgroupInfo *pVgroupInfo,
|
int32_t mmMonitorMnodeInfo(SMgmtWrapper *pWrapper, SMonClusterInfo *pClusterInfo, SMonVgroupInfo *pVgroupInfo,
|
||||||
SMonGrantInfo *pGrantInfo) {
|
SMonGrantInfo *pGrantInfo) {
|
||||||
SMnodeMgmt *pMgmt = pWrapper->pMgmt;
|
SMnodeMgmt *pMgmt = pWrapper->pMgmt;
|
|
@ -37,7 +37,7 @@ static void mmProcessQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) {
|
||||||
dError("msg:%p, failed to process since %s", pMsg, terrstr());
|
dError("msg:%p, failed to process since %s", pMsg, terrstr());
|
||||||
}
|
}
|
||||||
SRpcMsg rsp = {.handle = pRpc->handle, .code = code, .contLen = pMsg->rspLen, .pCont = pMsg->pRsp};
|
SRpcMsg rsp = {.handle = pRpc->handle, .code = code, .contLen = pMsg->rspLen, .pCont = pMsg->pRsp};
|
||||||
dndSendRsp(pMgmt->pWrapper, &rsp);
|
tmsgSendRsp(&rsp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ static void mmProcessQueryQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) {
|
||||||
if (pRpc->handle != NULL && code != 0) {
|
if (pRpc->handle != NULL && code != 0) {
|
||||||
dError("msg:%p, failed to process since %s", pMsg, terrstr());
|
dError("msg:%p, failed to process since %s", pMsg, terrstr());
|
||||||
SRpcMsg rsp = {.handle = pRpc->handle, .code = code, .ahandle = pRpc->ahandle};
|
SRpcMsg rsp = {.handle = pRpc->handle, .code = code, .ahandle = pRpc->ahandle};
|
||||||
dndSendRsp(pMgmt->pWrapper, &rsp);
|
tmsgSendRsp(&rsp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _TD_DND_QNODE_H_
|
|
||||||
#define _TD_DND_QNODE_H_
|
|
||||||
|
|
||||||
#include "dnd.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void qmGetMgmtFp(SMgmtWrapper *pMgmt);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*_TD_DND_QNODE_H_*/
|
|
|
@ -54,16 +54,16 @@ int32_t qmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void qmInitMsgHandles(SMgmtWrapper *pWrapper) {
|
void qmInitMsgHandle(SMgmtWrapper *pWrapper) {
|
||||||
// Requests handled by VNODE
|
// Requests handled by VNODE
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY, qmProcessQueryMsg, QND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY, qmProcessQueryMsg, QNODE_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY_CONTINUE, qmProcessQueryMsg, QND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY_CONTINUE, qmProcessQueryMsg, QNODE_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_FETCH, qmProcessFetchMsg, QND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_FETCH, qmProcessFetchMsg, QNODE_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_FETCH_RSP, qmProcessFetchMsg, QND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_FETCH_RSP, qmProcessFetchMsg, QNODE_HANDLE);
|
||||||
|
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_RES_READY, qmProcessFetchMsg, QND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_RES_READY, qmProcessFetchMsg, QNODE_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_TASKS_STATUS, qmProcessFetchMsg, QND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_TASKS_STATUS, qmProcessFetchMsg, QNODE_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_CANCEL_TASK, qmProcessFetchMsg, QND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_CANCEL_TASK, qmProcessFetchMsg, QNODE_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_TASK, qmProcessFetchMsg, QND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_TASK, qmProcessFetchMsg, QNODE_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_SHOW_TABLES, qmProcessFetchMsg, QND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_SHOW_TABLES, qmProcessFetchMsg, QNODE_HANDLE);
|
||||||
}
|
}
|
|
@ -112,7 +112,7 @@ int32_t qmOpen(SMgmtWrapper *pWrapper) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void qmGetMgmtFp(SMgmtWrapper *pWrapper) {
|
void qmSetMgmtFp(SMgmtWrapper *pWrapper) {
|
||||||
SMgmtFp mgmtFp = {0};
|
SMgmtFp mgmtFp = {0};
|
||||||
mgmtFp.openFp = qmOpen;
|
mgmtFp.openFp = qmOpen;
|
||||||
mgmtFp.closeFp = qmClose;
|
mgmtFp.closeFp = qmClose;
|
||||||
|
@ -120,7 +120,7 @@ void qmGetMgmtFp(SMgmtWrapper *pWrapper) {
|
||||||
mgmtFp.dropMsgFp = qmProcessDropReq;
|
mgmtFp.dropMsgFp = qmProcessDropReq;
|
||||||
mgmtFp.requiredFp = qmRequire;
|
mgmtFp.requiredFp = qmRequire;
|
||||||
|
|
||||||
qmInitMsgHandles(pWrapper);
|
qmInitMsgHandle(pWrapper);
|
||||||
pWrapper->name = "qnode";
|
pWrapper->name = "qnode";
|
||||||
pWrapper->fp = mgmtFp;
|
pWrapper->fp = mgmtFp;
|
||||||
}
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
static void qmSendRsp(SMgmtWrapper *pWrapper, SNodeMsg *pMsg, int32_t code) {
|
static void qmSendRsp(SMgmtWrapper *pWrapper, SNodeMsg *pMsg, int32_t code) {
|
||||||
SRpcMsg rsp = {.handle = pMsg->rpcMsg.handle, .ahandle = pMsg->rpcMsg.ahandle, .code = code};
|
SRpcMsg rsp = {.handle = pMsg->rpcMsg.handle, .ahandle = pMsg->rpcMsg.ahandle, .code = code};
|
||||||
dndSendRsp(pWrapper, &rsp);
|
tmsgSendRsp(&rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qmProcessQueryQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) {
|
static void qmProcessQueryQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) {
|
|
@ -1,31 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _TD_DND_SNODE_H_
|
|
||||||
#define _TD_DND_SNODE_H_
|
|
||||||
|
|
||||||
#include "dnd.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void smGetMgmtFp(SMgmtWrapper *pWrapper);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*_TD_DND_SNODE_H_*/
|
|
|
@ -54,8 +54,8 @@ int32_t smProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void smInitMsgHandles(SMgmtWrapper *pWrapper) {
|
void smInitMsgHandle(SMgmtWrapper *pWrapper) {
|
||||||
// Requests handled by SNODE
|
// Requests handled by SNODE
|
||||||
dndSetMsgHandle(pWrapper, TDMT_SND_TASK_DEPLOY, smProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_SND_TASK_DEPLOY, smProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_SND_TASK_EXEC, smProcessExecMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_SND_TASK_EXEC, smProcessExecMsg, DEFAULT_HANDLE);
|
||||||
}
|
}
|
|
@ -109,7 +109,7 @@ int32_t smOpen(SMgmtWrapper *pWrapper) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smGetMgmtFp(SMgmtWrapper *pWrapper) {
|
void smSetMgmtFp(SMgmtWrapper *pWrapper) {
|
||||||
SMgmtFp mgmtFp = {0};
|
SMgmtFp mgmtFp = {0};
|
||||||
mgmtFp.openFp = smOpen;
|
mgmtFp.openFp = smOpen;
|
||||||
mgmtFp.closeFp = smClose;
|
mgmtFp.closeFp = smClose;
|
||||||
|
@ -117,7 +117,7 @@ void smGetMgmtFp(SMgmtWrapper *pWrapper) {
|
||||||
mgmtFp.dropMsgFp = smProcessDropReq;
|
mgmtFp.dropMsgFp = smProcessDropReq;
|
||||||
mgmtFp.requiredFp = smRequire;
|
mgmtFp.requiredFp = smRequire;
|
||||||
|
|
||||||
smInitMsgHandles(pWrapper);
|
smInitMsgHandle(pWrapper);
|
||||||
pWrapper->name = "snode";
|
pWrapper->name = "snode";
|
||||||
pWrapper->fp = mgmtFp;
|
pWrapper->fp = mgmtFp;
|
||||||
}
|
}
|
|
@ -1,46 +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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _TD_DND_VNODES_H_
|
|
||||||
#define _TD_DND_VNODES_H_
|
|
||||||
|
|
||||||
#include "dnd.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int32_t openVnodes;
|
|
||||||
int32_t totalVnodes;
|
|
||||||
int32_t masterNum;
|
|
||||||
int64_t numOfSelectReqs;
|
|
||||||
int64_t numOfInsertReqs;
|
|
||||||
int64_t numOfInsertSuccessReqs;
|
|
||||||
int64_t numOfBatchInsertReqs;
|
|
||||||
int64_t numOfBatchInsertSuccessReqs;
|
|
||||||
} SVnodesStat;
|
|
||||||
|
|
||||||
void vmGetMgmtFp(SMgmtWrapper *pWrapper);
|
|
||||||
|
|
||||||
void vmMonitorVnodeLoads(SMgmtWrapper *pWrapper, SArray *pLoads);
|
|
||||||
int32_t vmMonitorTfsInfo(SMgmtWrapper *pWrapper, SMonDiskInfo *pInfo);
|
|
||||||
void vmMonitorVnodeReqs(SMgmtWrapper *pWrapper, SMonDnodeInfo *pInfo);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*_TD_DND_VNODES_H_*/
|
|
|
@ -30,6 +30,7 @@ static void vmGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) {
|
||||||
pCfg->tsdbCfg.keep1 = pCreate->daysToKeep2;
|
pCfg->tsdbCfg.keep1 = pCreate->daysToKeep2;
|
||||||
pCfg->tsdbCfg.keep2 = pCreate->daysToKeep0;
|
pCfg->tsdbCfg.keep2 = pCreate->daysToKeep0;
|
||||||
pCfg->tsdbCfg.lruCacheSize = pCreate->cacheBlockSize;
|
pCfg->tsdbCfg.lruCacheSize = pCreate->cacheBlockSize;
|
||||||
|
pCfg->tsdbCfg.retentions = pCreate->pRetensions;
|
||||||
pCfg->metaCfg.lruSize = pCreate->cacheBlockSize;
|
pCfg->metaCfg.lruSize = pCreate->cacheBlockSize;
|
||||||
pCfg->walCfg.fsyncPeriod = pCreate->fsyncPeriod;
|
pCfg->walCfg.fsyncPeriod = pCreate->fsyncPeriod;
|
||||||
pCfg->walCfg.level = pCreate->walLevel;
|
pCfg->walCfg.level = pCreate->walLevel;
|
||||||
|
@ -70,6 +71,7 @@ int32_t vmProcessCreateVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pMsg) {
|
||||||
|
|
||||||
SVnodeObj *pVnode = vmAcquireVnode(pMgmt, createReq.vgId);
|
SVnodeObj *pVnode = vmAcquireVnode(pMgmt, createReq.vgId);
|
||||||
if (pVnode != NULL) {
|
if (pVnode != NULL) {
|
||||||
|
tFreeSCreateVnodeReq(&createReq);
|
||||||
dDebug("vgId:%d, already exist", createReq.vgId);
|
dDebug("vgId:%d, already exist", createReq.vgId);
|
||||||
vmReleaseVnode(pMgmt, pVnode);
|
vmReleaseVnode(pMgmt, pVnode);
|
||||||
terrno = TSDB_CODE_DND_VNODE_ALREADY_DEPLOYED;
|
terrno = TSDB_CODE_DND_VNODE_ALREADY_DEPLOYED;
|
||||||
|
@ -88,12 +90,14 @@ int32_t vmProcessCreateVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pMsg) {
|
||||||
vnodeCfg.dbId = wrapperCfg.dbUid;
|
vnodeCfg.dbId = wrapperCfg.dbUid;
|
||||||
SVnode *pImpl = vnodeOpen(wrapperCfg.path, &vnodeCfg);
|
SVnode *pImpl = vnodeOpen(wrapperCfg.path, &vnodeCfg);
|
||||||
if (pImpl == NULL) {
|
if (pImpl == NULL) {
|
||||||
|
tFreeSCreateVnodeReq(&createReq);
|
||||||
dError("vgId:%d, failed to create vnode since %s", createReq.vgId, terrstr());
|
dError("vgId:%d, failed to create vnode since %s", createReq.vgId, terrstr());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = vmOpenVnode(pMgmt, &wrapperCfg, pImpl);
|
int32_t code = vmOpenVnode(pMgmt, &wrapperCfg, pImpl);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
|
tFreeSCreateVnodeReq(&createReq);
|
||||||
dError("vgId:%d, failed to open vnode since %s", createReq.vgId, terrstr());
|
dError("vgId:%d, failed to open vnode since %s", createReq.vgId, terrstr());
|
||||||
vnodeClose(pImpl);
|
vnodeClose(pImpl);
|
||||||
vnodeDestroy(wrapperCfg.path);
|
vnodeDestroy(wrapperCfg.path);
|
||||||
|
@ -103,6 +107,7 @@ int32_t vmProcessCreateVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pMsg) {
|
||||||
|
|
||||||
code = vmWriteVnodesToFile(pMgmt);
|
code = vmWriteVnodesToFile(pMgmt);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
|
tFreeSCreateVnodeReq(&createReq);
|
||||||
vnodeClose(pImpl);
|
vnodeClose(pImpl);
|
||||||
vnodeDestroy(wrapperCfg.path);
|
vnodeDestroy(wrapperCfg.path);
|
||||||
terrno = code;
|
terrno = code;
|
||||||
|
@ -233,51 +238,51 @@ int32_t vmProcessCompactVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pMsg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vmInitMsgHandles(SMgmtWrapper *pWrapper) {
|
void vmInitMsgHandle(SMgmtWrapper *pWrapper) {
|
||||||
// Requests handled by VNODE
|
// Requests handled by VNODE
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_SUBMIT, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_SUBMIT, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY, (NodeMsgFp)vmProcessQueryMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY, (NodeMsgFp)vmProcessQueryMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY_CONTINUE, (NodeMsgFp)vmProcessQueryMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY_CONTINUE, (NodeMsgFp)vmProcessQueryMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_FETCH, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_FETCH, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_FETCH_RSP, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_FETCH_RSP, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_ALTER_TABLE, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_ALTER_TABLE, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_UPDATE_TAG_VAL, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_UPDATE_TAG_VAL, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_TABLE_META, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_TABLE_META, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_TABLES_META, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_TABLES_META, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_CONSUME, (NodeMsgFp)vmProcessQueryMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_CONSUME, (NodeMsgFp)vmProcessQueryMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_QUERY, (NodeMsgFp)vmProcessQueryMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_QUERY, (NodeMsgFp)vmProcessQueryMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_CONNECT, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_CONNECT, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_DISCONNECT, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_DISCONNECT, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_SET_CUR, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_SET_CUR, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_RES_READY, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_RES_READY, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_TASKS_STATUS, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_TASKS_STATUS, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_CANCEL_TASK, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_CANCEL_TASK, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_TASK, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_TASK, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_CREATE_STB, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_CREATE_STB, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_ALTER_STB, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_ALTER_STB, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_STB, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_STB, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_CREATE_TABLE, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_CREATE_TABLE, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_ALTER_TABLE, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_ALTER_TABLE, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_TABLE, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_TABLE, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_CREATE_SMA, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_CREATE_SMA, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_CANCEL_SMA, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_CANCEL_SMA, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_SMA, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_DROP_SMA, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_SHOW_TABLES, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_SHOW_TABLES, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_SHOW_TABLES_FETCH, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_SHOW_TABLES_FETCH, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_SET_CONN, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_SET_CONN, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_REB, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_REB, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_SET_CUR, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_MQ_SET_CUR, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_CONSUME, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_CONSUME, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_TASK_DEPLOY, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_TASK_DEPLOY, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY_HEARTBEAT, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_QUERY_HEARTBEAT, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_TASK_PIPE_EXEC, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_TASK_PIPE_EXEC, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_TASK_MERGE_EXEC, (NodeMsgFp)vmProcessMergeMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_TASK_MERGE_EXEC, (NodeMsgFp)vmProcessMergeMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_TASK_WRITE_EXEC, (NodeMsgFp)vmProcessWriteMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_TASK_WRITE_EXEC, (NodeMsgFp)vmProcessWriteMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_VND_STREAM_TRIGGER, (NodeMsgFp)vmProcessFetchMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_VND_STREAM_TRIGGER, (NodeMsgFp)vmProcessFetchMsg, DEFAULT_HANDLE);
|
||||||
|
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_VNODE, vmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_CREATE_VNODE, vmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_ALTER_VNODE, vmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_ALTER_VNODE, vmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_VNODE, vmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_DROP_VNODE, vmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_SYNC_VNODE, vmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_SYNC_VNODE, vmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
dndSetMsgHandle(pWrapper, TDMT_DND_COMPACT_VNODE, vmProcessMgmtMsg, VND_VGID);
|
dndSetMsgHandle(pWrapper, TDMT_DND_COMPACT_VNODE, vmProcessMgmtMsg, DEFAULT_HANDLE);
|
||||||
}
|
}
|
|
@ -333,13 +333,13 @@ static int32_t vmRequire(SMgmtWrapper *pWrapper, bool *required) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vmGetMgmtFp(SMgmtWrapper *pWrapper) {
|
void vmSetMgmtFp(SMgmtWrapper *pWrapper) {
|
||||||
SMgmtFp mgmtFp = {0};
|
SMgmtFp mgmtFp = {0};
|
||||||
mgmtFp.openFp = vmInit;
|
mgmtFp.openFp = vmInit;
|
||||||
mgmtFp.closeFp = vmCleanup;
|
mgmtFp.closeFp = vmCleanup;
|
||||||
mgmtFp.requiredFp = vmRequire;
|
mgmtFp.requiredFp = vmRequire;
|
||||||
|
|
||||||
vmInitMsgHandles(pWrapper);
|
vmInitMsgHandle(pWrapper);
|
||||||
pWrapper->name = "vnode";
|
pWrapper->name = "vnode";
|
||||||
pWrapper->fp = mgmtFp;
|
pWrapper->fp = mgmtFp;
|
||||||
}
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
static void vmSendRsp(SMgmtWrapper *pWrapper, SNodeMsg *pMsg, int32_t code) {
|
static void vmSendRsp(SMgmtWrapper *pWrapper, SNodeMsg *pMsg, int32_t code) {
|
||||||
SRpcMsg rsp = {.handle = pMsg->rpcMsg.handle, .ahandle = pMsg->rpcMsg.ahandle, .code = code};
|
SRpcMsg rsp = {.handle = pMsg->rpcMsg.handle, .ahandle = pMsg->rpcMsg.ahandle, .code = code};
|
||||||
dndSendRsp(pWrapper, &rsp);
|
tmsgSendRsp(&rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vmProcessMgmtQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) {
|
static void vmProcessMgmtQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) {
|
||||||
|
@ -116,7 +116,7 @@ static void vmProcessWriteQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numO
|
||||||
int32_t code = vnodeApplyWMsg(pVnode->pImpl, pRpc, &pRsp);
|
int32_t code = vnodeApplyWMsg(pVnode->pImpl, pRpc, &pRsp);
|
||||||
if (pRsp != NULL) {
|
if (pRsp != NULL) {
|
||||||
pRsp->ahandle = pRpc->ahandle;
|
pRsp->ahandle = pRpc->ahandle;
|
||||||
dndSendRsp(pVnode->pWrapper, pRsp);
|
tmsgSendRsp(pRsp);
|
||||||
taosMemoryFree(pRsp);
|
taosMemoryFree(pRsp);
|
||||||
} else {
|
} else {
|
||||||
if (code != 0 && terrno != 0) code = terrno;
|
if (code != 0 && terrno != 0) code = terrno;
|
|
@ -160,10 +160,8 @@ static int32_t mndConsumerActionDelete(SSdb *pSdb, SMqConsumerObj *pConsumer) {
|
||||||
|
|
||||||
static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer, SMqConsumerObj *pNewConsumer) {
|
static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer, SMqConsumerObj *pNewConsumer) {
|
||||||
mTrace("consumer:%" PRId64 ", perform update action", pOldConsumer->consumerId);
|
mTrace("consumer:%" PRId64 ", perform update action", pOldConsumer->consumerId);
|
||||||
pOldConsumer->epoch++;
|
|
||||||
|
|
||||||
// TODO handle update
|
|
||||||
/*taosWLockLatch(&pOldConsumer->lock);*/
|
/*taosWLockLatch(&pOldConsumer->lock);*/
|
||||||
|
atomic_add_fetch_32(&pOldConsumer->epoch, 1);
|
||||||
/*taosWUnLockLatch(&pOldConsumer->lock);*/
|
/*taosWUnLockLatch(&pOldConsumer->lock);*/
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -69,7 +69,8 @@ void mndCleanupDb(SMnode *pMnode) {}
|
||||||
static SSdbRaw *mndDbActionEncode(SDbObj *pDb) {
|
static SSdbRaw *mndDbActionEncode(SDbObj *pDb) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
SSdbRaw *pRaw = sdbAllocRaw(SDB_DB, TSDB_DB_VER_NUMBER, sizeof(SDbObj) + TSDB_DB_RESERVE_SIZE);
|
SSdbRaw *pRaw = sdbAllocRaw(SDB_DB, TSDB_DB_VER_NUMBER,
|
||||||
|
sizeof(SDbObj) + pDb->cfg.numOfRetensions * sizeof(SRetention) + TSDB_DB_RESERVE_SIZE);
|
||||||
if (pRaw == NULL) goto DB_ENCODE_OVER;
|
if (pRaw == NULL) goto DB_ENCODE_OVER;
|
||||||
|
|
||||||
int32_t dataPos = 0;
|
int32_t dataPos = 0;
|
||||||
|
|
|
@ -52,7 +52,7 @@ int32_t mndProcessFetchMsg(SNodeMsg *pReq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mndInitQuery(SMnode *pMnode) {
|
int32_t mndInitQuery(SMnode *pMnode) {
|
||||||
if (qWorkerInit(NODE_TYPE_MNODE, MND_VGID, NULL, (void **)&pMnode->pQuery, &pMnode->msgCb) != 0) {
|
if (qWorkerInit(NODE_TYPE_MNODE, MNODE_HANDLE, NULL, (void **)&pMnode->pQuery, &pMnode->msgCb) != 0) {
|
||||||
mError("failed to init qworker in mnode since %s", terrstr());
|
mError("failed to init qworker in mnode since %s", terrstr());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -471,6 +471,9 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib
|
||||||
consumerEp.consumerId = -1;
|
consumerEp.consumerId = -1;
|
||||||
consumerEp.epSet = plan->execNode.epSet;
|
consumerEp.epSet = plan->execNode.epSet;
|
||||||
consumerEp.vgId = plan->execNode.nodeId;
|
consumerEp.vgId = plan->execNode.nodeId;
|
||||||
|
|
||||||
|
mDebug("init subscribption %s, assign vg: %d", pSub->key, consumerEp.vgId);
|
||||||
|
|
||||||
int32_t msgLen;
|
int32_t msgLen;
|
||||||
if (qSubPlanToString(plan, &consumerEp.qmsg, &msgLen) < 0) {
|
if (qSubPlanToString(plan, &consumerEp.qmsg, &msgLen) < 0) {
|
||||||
sdbRelease(pSdb, pVgroup);
|
sdbRelease(pSdb, pVgroup);
|
||||||
|
|
|
@ -212,19 +212,24 @@ static int32_t mndProcessGetSubEpReq(SNodeMsg *pMsg) {
|
||||||
terrno = TSDB_CODE_MND_CONSUMER_NOT_EXIST;
|
terrno = TSDB_CODE_MND_CONSUMER_NOT_EXIST;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
//TODO add lock
|
||||||
ASSERT(strcmp(pReq->cgroup, pConsumer->cgroup) == 0);
|
ASSERT(strcmp(pReq->cgroup, pConsumer->cgroup) == 0);
|
||||||
|
int32_t serverEpoch = pConsumer->epoch;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
int32_t hbStatus = atomic_load_32(&pConsumer->hbStatus);
|
int32_t hbStatus = atomic_load_32(&pConsumer->hbStatus);
|
||||||
mTrace("try to get sub ep, old val: %d", hbStatus);
|
mDebug("consumer %ld epoch(%d) try to get sub ep, server epoch %d, old val: %d", consumerId, epoch, serverEpoch, hbStatus);
|
||||||
atomic_store_32(&pConsumer->hbStatus, 0);
|
atomic_store_32(&pConsumer->hbStatus, 0);
|
||||||
/*SSdbRaw *pConsumerRaw = mndConsumerActionEncode(pConsumer);*/
|
/*SSdbRaw *pConsumerRaw = mndConsumerActionEncode(pConsumer);*/
|
||||||
/*sdbSetRawStatus(pConsumerRaw, SDB_STATUS_READY);*/
|
/*sdbSetRawStatus(pConsumerRaw, SDB_STATUS_READY);*/
|
||||||
/*sdbWrite(pMnode->pSdb, pConsumerRaw);*/
|
/*sdbWrite(pMnode->pSdb, pConsumerRaw);*/
|
||||||
|
|
||||||
strcpy(rsp.cgroup, pReq->cgroup);
|
strcpy(rsp.cgroup, pReq->cgroup);
|
||||||
if (epoch != pConsumer->epoch) {
|
if (epoch != serverEpoch) {
|
||||||
mInfo("send new assignment to consumer, consumer epoch %d, server epoch %d", epoch, pConsumer->epoch);
|
mInfo("send new assignment to consumer %ld, consumer epoch %d, server epoch %d", pConsumer->consumerId, epoch, serverEpoch);
|
||||||
|
mDebug("consumer %ld try r lock", consumerId);
|
||||||
|
taosRLockLatch(&pConsumer->lock);
|
||||||
|
mDebug("consumer %ld r locked", consumerId);
|
||||||
SArray *pTopics = pConsumer->currentTopics;
|
SArray *pTopics = pConsumer->currentTopics;
|
||||||
int32_t sz = taosArrayGetSize(pTopics);
|
int32_t sz = taosArrayGetSize(pTopics);
|
||||||
rsp.topics = taosArrayInit(sz, sizeof(SMqSubTopicEp));
|
rsp.topics = taosArrayInit(sz, sizeof(SMqSubTopicEp));
|
||||||
|
@ -238,7 +243,7 @@ static int32_t mndProcessGetSubEpReq(SNodeMsg *pMsg) {
|
||||||
SMqSubConsumer *pSubConsumer = taosArrayGet(pSub->consumers, j);
|
SMqSubConsumer *pSubConsumer = taosArrayGet(pSub->consumers, j);
|
||||||
if (consumerId == pSubConsumer->consumerId) {
|
if (consumerId == pSubConsumer->consumerId) {
|
||||||
int32_t vgsz = taosArrayGetSize(pSubConsumer->vgInfo);
|
int32_t vgsz = taosArrayGetSize(pSubConsumer->vgInfo);
|
||||||
mInfo("topic %s has %d vg", topicName, pConsumer->epoch);
|
mInfo("topic %s has %d vg", topicName, serverEpoch);
|
||||||
SMqSubTopicEp topicEp;
|
SMqSubTopicEp topicEp;
|
||||||
strcpy(topicEp.topic, topicName);
|
strcpy(topicEp.topic, topicName);
|
||||||
topicEp.vgs = taosArrayInit(vgsz, sizeof(SMqSubVgEp));
|
topicEp.vgs = taosArrayInit(vgsz, sizeof(SMqSubVgEp));
|
||||||
|
@ -264,6 +269,8 @@ static int32_t mndProcessGetSubEpReq(SNodeMsg *pMsg) {
|
||||||
}
|
}
|
||||||
mndReleaseSubscribe(pMnode, pSub);
|
mndReleaseSubscribe(pMnode, pSub);
|
||||||
}
|
}
|
||||||
|
taosRUnLockLatch(&pConsumer->lock);
|
||||||
|
mDebug("consumer %ld r unlock", consumerId);
|
||||||
}
|
}
|
||||||
int32_t tlen = sizeof(SMqRspHead) + tEncodeSMqCMGetSubEpRsp(NULL, &rsp);
|
int32_t tlen = sizeof(SMqRspHead) + tEncodeSMqCMGetSubEpRsp(NULL, &rsp);
|
||||||
void *buf = rpcMallocCont(tlen);
|
void *buf = rpcMallocCont(tlen);
|
||||||
|
@ -272,7 +279,7 @@ static int32_t mndProcessGetSubEpReq(SNodeMsg *pMsg) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
((SMqRspHead *)buf)->mqMsgType = TMQ_MSG_TYPE__EP_RSP;
|
((SMqRspHead *)buf)->mqMsgType = TMQ_MSG_TYPE__EP_RSP;
|
||||||
((SMqRspHead *)buf)->epoch = pConsumer->epoch;
|
((SMqRspHead *)buf)->epoch = serverEpoch;
|
||||||
((SMqRspHead *)buf)->consumerId = pConsumer->consumerId;
|
((SMqRspHead *)buf)->consumerId = pConsumer->consumerId;
|
||||||
|
|
||||||
void *abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
|
void *abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
|
||||||
|
@ -395,7 +402,7 @@ static int32_t mndProcessDoRebalanceMsg(SNodeMsg *pMsg) {
|
||||||
SMqSubscribeObj *pSub = mndAcquireSubscribeByKey(pMnode, pRebSub->key);
|
SMqSubscribeObj *pSub = mndAcquireSubscribeByKey(pMnode, pRebSub->key);
|
||||||
taosMemoryFreeClear(pRebSub->key);
|
taosMemoryFreeClear(pRebSub->key);
|
||||||
|
|
||||||
mInfo("mq rebalance subscription: %s", pSub->key);
|
mInfo("mq rebalance subscription: %s, vgNum: %d, unassignedVg: %d", pSub->key, pSub->vgNum, (int32_t)taosArrayGetSize(pSub->unassignedVg));
|
||||||
|
|
||||||
// remove lost consumer
|
// remove lost consumer
|
||||||
for (int32_t i = 0; i < taosArrayGetSize(pRebSub->lostConsumers); i++) {
|
for (int32_t i = 0; i < taosArrayGetSize(pRebSub->lostConsumers); i++) {
|
||||||
|
@ -442,6 +449,9 @@ static int32_t mndProcessDoRebalanceMsg(SNodeMsg *pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SMqConsumerObj *pRebConsumer = mndAcquireConsumer(pMnode, pSubConsumer->consumerId);
|
SMqConsumerObj *pRebConsumer = mndAcquireConsumer(pMnode, pSubConsumer->consumerId);
|
||||||
|
mDebug("consumer %ld try w lock", pRebConsumer->consumerId);
|
||||||
|
taosWLockLatch(&pRebConsumer->lock);
|
||||||
|
mDebug("consumer %ld w locked", pRebConsumer->consumerId);
|
||||||
int32_t status = atomic_load_32(&pRebConsumer->status);
|
int32_t status = atomic_load_32(&pRebConsumer->status);
|
||||||
if (vgThisConsumerAfterRb != vgThisConsumerBeforeRb ||
|
if (vgThisConsumerAfterRb != vgThisConsumerBeforeRb ||
|
||||||
(vgThisConsumerAfterRb != 0 && status != MQ_CONSUMER_STATUS__ACTIVE) ||
|
(vgThisConsumerAfterRb != 0 && status != MQ_CONSUMER_STATUS__ACTIVE) ||
|
||||||
|
@ -462,6 +472,8 @@ static int32_t mndProcessDoRebalanceMsg(SNodeMsg *pMsg) {
|
||||||
sdbSetRawStatus(pConsumerRaw, SDB_STATUS_READY);
|
sdbSetRawStatus(pConsumerRaw, SDB_STATUS_READY);
|
||||||
mndTransAppendCommitlog(pTrans, pConsumerRaw);
|
mndTransAppendCommitlog(pTrans, pConsumerRaw);
|
||||||
}
|
}
|
||||||
|
taosWUnLockLatch(&pRebConsumer->lock);
|
||||||
|
mDebug("consumer %ld w unlock", pRebConsumer->consumerId);
|
||||||
mndReleaseConsumer(pMnode, pRebConsumer);
|
mndReleaseConsumer(pMnode, pRebConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,13 +55,14 @@ typedef struct STsdbCfg {
|
||||||
int8_t precision;
|
int8_t precision;
|
||||||
int8_t update;
|
int8_t update;
|
||||||
int8_t compression;
|
int8_t compression;
|
||||||
uint64_t lruCacheSize;
|
|
||||||
int32_t daysPerFile;
|
int32_t daysPerFile;
|
||||||
int32_t minRowsPerFileBlock;
|
int32_t minRowsPerFileBlock;
|
||||||
int32_t maxRowsPerFileBlock;
|
int32_t maxRowsPerFileBlock;
|
||||||
int32_t keep;
|
int32_t keep;
|
||||||
int32_t keep1;
|
int32_t keep1;
|
||||||
int32_t keep2;
|
int32_t keep2;
|
||||||
|
uint64_t lruCacheSize;
|
||||||
|
SArray *retentions;
|
||||||
} STsdbCfg;
|
} STsdbCfg;
|
||||||
|
|
||||||
// query condition to build multi-table data block iterator
|
// query condition to build multi-table data block iterator
|
||||||
|
@ -171,9 +172,9 @@ tsdbReaderT *tsdbQueryTables(STsdb *tsdb, STsdbQueryCond *pCond, STableGroupInfo
|
||||||
|
|
||||||
tsdbReaderT tsdbQueryCacheLast(STsdb *tsdb, STsdbQueryCond *pCond, STableGroupInfo *groupList, uint64_t qId, void* pMemRef);
|
tsdbReaderT tsdbQueryCacheLast(STsdb *tsdb, STsdbQueryCond *pCond, STableGroupInfo *groupList, uint64_t qId, void* pMemRef);
|
||||||
|
|
||||||
int32_t tsdbGetFileBlocksDistInfo(tsdbReaderT* queryHandle, STableBlockDistInfo* pTableBlockInfo);
|
int32_t tsdbGetFileBlocksDistInfo(tsdbReaderT* pReader, STableBlockDistInfo* pTableBlockInfo);
|
||||||
|
|
||||||
bool isTsdbCacheLastRow(tsdbReaderT* pTsdbReadHandle);
|
bool isTsdbCacheLastRow(tsdbReaderT* pReader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
@ -112,10 +112,10 @@ typedef struct {
|
||||||
#else
|
#else
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int16_t colId;
|
int16_t colId;
|
||||||
uint8_t bitmap : 1; // 0: has bitmap if has NULL/NORM rows, 1: no bitmap if all rows are NORM
|
uint16_t type : 6;
|
||||||
uint8_t reserve : 7;
|
uint16_t blen : 10; // bitmap length(TODO: full UT for the bitmap compress of various data input)
|
||||||
uint8_t type;
|
uint32_t bitmap : 1; // 0: has bitmap if has NULL/NORM rows, 1: no bitmap if all rows are NORM
|
||||||
int32_t len;
|
uint32_t len : 31; // data length + bitmap length
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
} SBlockColV0;
|
} SBlockColV0;
|
||||||
|
|
||||||
|
|
|
@ -1281,7 +1281,7 @@ int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDFile *pDF
|
||||||
uint32_t tsizeAggr = (uint32_t)tsdbBlockAggrSize(nColsNotAllNull, SBlockVerLatest);
|
uint32_t tsizeAggr = (uint32_t)tsdbBlockAggrSize(nColsNotAllNull, SBlockVerLatest);
|
||||||
int32_t keyLen = 0;
|
int32_t keyLen = 0;
|
||||||
int32_t nBitmaps = (int32_t)TD_BITMAP_BYTES(rowsToWrite);
|
int32_t nBitmaps = (int32_t)TD_BITMAP_BYTES(rowsToWrite);
|
||||||
int32_t tBitmaps = 0;
|
// int32_t tBitmaps = 0;
|
||||||
|
|
||||||
for (int ncol = 0; ncol < pDataCols->numOfCols; ++ncol) {
|
for (int ncol = 0; ncol < pDataCols->numOfCols; ++ncol) {
|
||||||
// All not NULL columns finish
|
// All not NULL columns finish
|
||||||
|
@ -1297,7 +1297,10 @@ int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDFile *pDF
|
||||||
|
|
||||||
#ifdef TD_SUPPORT_BITMAP
|
#ifdef TD_SUPPORT_BITMAP
|
||||||
int32_t tBitmaps = 0;
|
int32_t tBitmaps = 0;
|
||||||
|
int32_t tBitmapsLen = 0;
|
||||||
if ((ncol != 0) && !TD_COL_ROWS_NORM(pBlockCol)) {
|
if ((ncol != 0) && !TD_COL_ROWS_NORM(pBlockCol)) {
|
||||||
|
tBitmaps = nBitmaps;
|
||||||
|
#if 0
|
||||||
if (IS_VAR_DATA_TYPE(pDataCol->type)) {
|
if (IS_VAR_DATA_TYPE(pDataCol->type)) {
|
||||||
tBitmaps = nBitmaps;
|
tBitmaps = nBitmaps;
|
||||||
tlen += tBitmaps;
|
tlen += tBitmaps;
|
||||||
|
@ -1305,16 +1308,17 @@ int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDFile *pDF
|
||||||
tBitmaps = (int32_t)ceil((double)nBitmaps / TYPE_BYTES[pDataCol->type]);
|
tBitmaps = (int32_t)ceil((double)nBitmaps / TYPE_BYTES[pDataCol->type]);
|
||||||
tlen += tBitmaps * TYPE_BYTES[pDataCol->type];
|
tlen += tBitmaps * TYPE_BYTES[pDataCol->type];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// move bitmap parts ahead
|
// move bitmap parts ahead
|
||||||
// TODO: put bitmap part to the 1st location(pBitmap points to pData) to avoid the memmove
|
// TODO: put bitmap part to the 1st location(pBitmap points to pData) to avoid the memmove
|
||||||
memcpy(POINTER_SHIFT(pDataCol->pData, pDataCol->len), pDataCol->pBitmap, nBitmaps);
|
// memcpy(POINTER_SHIFT(pDataCol->pData, pDataCol->len), pDataCol->pBitmap, nBitmaps);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *tptr;
|
void *tptr, *bptr;
|
||||||
|
|
||||||
// Make room
|
// Make room
|
||||||
if (tsdbMakeRoom(ppBuf, lsize + tlen + COMP_OVERFLOW_BYTES + sizeof(TSCKSUM)) < 0) {
|
if (tsdbMakeRoom(ppBuf, lsize + tlen + tBitmaps + 2 * COMP_OVERFLOW_BYTES + sizeof(TSCKSUM)) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pBlockData = (SBlockData *)(*ppBuf);
|
pBlockData = (SBlockData *)(*ppBuf);
|
||||||
|
@ -1327,23 +1331,44 @@ int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDFile *pDF
|
||||||
|
|
||||||
// Compress or just copy
|
// Compress or just copy
|
||||||
if (pCfg->compression) {
|
if (pCfg->compression) {
|
||||||
|
#if 0
|
||||||
flen = (*(tDataTypes[pDataCol->type].compFunc))((char *)pDataCol->pData, tlen, rowsToWrite + tBitmaps, tptr,
|
flen = (*(tDataTypes[pDataCol->type].compFunc))((char *)pDataCol->pData, tlen, rowsToWrite + tBitmaps, tptr,
|
||||||
tlen + COMP_OVERFLOW_BYTES, pCfg->compression, *ppCBuf,
|
tlen + COMP_OVERFLOW_BYTES, pCfg->compression, *ppCBuf,
|
||||||
tlen + COMP_OVERFLOW_BYTES);
|
tlen + COMP_OVERFLOW_BYTES);
|
||||||
|
#endif
|
||||||
|
flen = (*(tDataTypes[pDataCol->type].compFunc))((char *)pDataCol->pData, tlen, rowsToWrite, tptr,
|
||||||
|
tlen + COMP_OVERFLOW_BYTES, pCfg->compression, *ppCBuf,
|
||||||
|
tlen + COMP_OVERFLOW_BYTES);
|
||||||
|
if (tBitmaps > 0) {
|
||||||
|
bptr = POINTER_SHIFT(pBlockData, lsize + flen);
|
||||||
|
tBitmapsLen =
|
||||||
|
tsCompressTinyint((char *)pDataCol->pBitmap, tBitmaps, tBitmaps, bptr, tBitmaps + COMP_OVERFLOW_BYTES,
|
||||||
|
pCfg->compression, *ppCBuf, tBitmaps + COMP_OVERFLOW_BYTES);
|
||||||
|
TASSERT((tBitmapsLen > 0) && (tBitmapsLen <= (tBitmaps + COMP_OVERFLOW_BYTES)));
|
||||||
|
flen += tBitmapsLen;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
flen = tlen;
|
flen = tlen;
|
||||||
memcpy(tptr, pDataCol->pData, flen);
|
memcpy(tptr, pDataCol->pData, flen);
|
||||||
|
if (tBitmaps > 0) {
|
||||||
|
bptr = POINTER_SHIFT(pBlockData, lsize + flen);
|
||||||
|
memcpy(bptr, pDataCol->pBitmap, tBitmaps);
|
||||||
|
tBitmapsLen = tBitmaps;
|
||||||
|
flen += tBitmapsLen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add checksum
|
// Add checksum
|
||||||
ASSERT(flen > 0);
|
ASSERT(flen > 0);
|
||||||
|
ASSERT(tBitmapsLen <= 1024);
|
||||||
flen += sizeof(TSCKSUM);
|
flen += sizeof(TSCKSUM);
|
||||||
taosCalcChecksumAppend(0, (uint8_t *)tptr, flen);
|
taosCalcChecksumAppend(0, (uint8_t *)tptr, flen);
|
||||||
tsdbUpdateDFileMagic(pDFile, POINTER_SHIFT(tptr, flen - sizeof(TSCKSUM)));
|
tsdbUpdateDFileMagic(pDFile, POINTER_SHIFT(tptr, flen - sizeof(TSCKSUM)));
|
||||||
|
|
||||||
if (ncol != 0) {
|
if (ncol != 0) {
|
||||||
tsdbSetBlockColOffset(pBlockCol, toffset);
|
tsdbSetBlockColOffset(pBlockCol, toffset);
|
||||||
pBlockCol->len = flen;
|
pBlockCol->len = flen; // data + bitmaps
|
||||||
|
pBlockCol->blen = tBitmapsLen;
|
||||||
++tcol;
|
++tcol;
|
||||||
} else {
|
} else {
|
||||||
keyLen = flen;
|
keyLen = flen;
|
||||||
|
|
|
@ -3046,8 +3046,8 @@ bool tsdbGetExternalRow(tsdbReaderT pHandle) {
|
||||||
// return code;
|
// return code;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
bool isTsdbCacheLastRow(tsdbReaderT* pTsdbReadHandle) {
|
bool isTsdbCacheLastRow(tsdbReaderT* pReader) {
|
||||||
return ((STsdbReadHandle *)pTsdbReadHandle)->cachelastrow > TSDB_CACHED_TYPE_NONE;
|
return ((STsdbReadHandle *)pReader)->cachelastrow > TSDB_CACHED_TYPE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t checkForCachedLastRow(STsdbReadHandle* pTsdbReadHandle, STableGroupInfo *groupList) {
|
int32_t checkForCachedLastRow(STsdbReadHandle* pTsdbReadHandle, STableGroupInfo *groupList) {
|
||||||
|
|
|
@ -21,9 +21,8 @@ static void tsdbResetReadTable(SReadH *pReadh);
|
||||||
static void tsdbResetReadFile(SReadH *pReadh);
|
static void tsdbResetReadFile(SReadH *pReadh);
|
||||||
static int tsdbLoadBlockOffset(SReadH *pReadh, SBlock *pBlock);
|
static int tsdbLoadBlockOffset(SReadH *pReadh, SBlock *pBlock);
|
||||||
static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDataCols);
|
static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDataCols);
|
||||||
static int tsdbCheckAndDecodeColumnData(SDataCol *pDataCol, void *content, int32_t len, int8_t comp, int numOfRows,
|
static int tsdbCheckAndDecodeColumnData(SDataCol *pDataCol, void *content, int32_t len, int32_t bitmapLen, int8_t comp,
|
||||||
int numOfBitmaps, int lenOfBitmaps, int maxPoints, char *buffer,
|
int numOfRows, int numOfBitmaps, int maxPoints, char *buffer, int bufferSize);
|
||||||
int bufferSize);
|
|
||||||
static int tsdbLoadBlockDataColsImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDataCols, const int16_t *colIds,
|
static int tsdbLoadBlockDataColsImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDataCols, const int16_t *colIds,
|
||||||
int numOfColIds);
|
int numOfColIds);
|
||||||
static int tsdbLoadColData(SReadH *pReadh, SDFile *pDFile, SBlock *pBlock, SBlockCol *pBlockCol, SDataCol *pDataCol);
|
static int tsdbLoadColData(SReadH *pReadh, SDFile *pDFile, SBlock *pBlock, SBlockCol *pBlockCol, SDataCol *pDataCol);
|
||||||
|
@ -548,7 +547,7 @@ static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDat
|
||||||
if (dcol != 0 && ccol >= pBlockData->numOfCols) {
|
if (dcol != 0 && ccol >= pBlockData->numOfCols) {
|
||||||
// Set current column as NULL and forward
|
// Set current column as NULL and forward
|
||||||
dataColReset(pDataCol);
|
dataColReset(pDataCol);
|
||||||
dcol++;
|
++dcol;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,9 +566,11 @@ static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDat
|
||||||
TD_SET_COL_ROWS_NORM(pDataCol);
|
TD_SET_COL_ROWS_NORM(pDataCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tBitmaps = 0;
|
// int32_t tBitmaps = 0;
|
||||||
int32_t tLenBitmap = 0;
|
int32_t tLenBitmap = 0;
|
||||||
if ((dcol != 0) && !TD_COL_ROWS_NORM(pBlockCol)) {
|
if ((dcol != 0) && !TD_COL_ROWS_NORM(pBlockCol)) {
|
||||||
|
tLenBitmap = nBitmaps;
|
||||||
|
#if 0
|
||||||
if (IS_VAR_DATA_TYPE(pDataCol->type)) {
|
if (IS_VAR_DATA_TYPE(pDataCol->type)) {
|
||||||
tBitmaps = nBitmaps;
|
tBitmaps = nBitmaps;
|
||||||
tLenBitmap = tBitmaps;
|
tLenBitmap = tBitmaps;
|
||||||
|
@ -577,17 +578,18 @@ static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDat
|
||||||
tBitmaps = (int32_t)ceil((double)nBitmaps / TYPE_BYTES[pDataCol->type]);
|
tBitmaps = (int32_t)ceil((double)nBitmaps / TYPE_BYTES[pDataCol->type]);
|
||||||
tLenBitmap = tBitmaps * TYPE_BYTES[pDataCol->type];
|
tLenBitmap = tBitmaps * TYPE_BYTES[pDataCol->type];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcolId == pDataCol->colId) {
|
if (tcolId == pDataCol->colId) {
|
||||||
if (pBlock->algorithm == TWO_STAGE_COMP) {
|
if (pBlock->algorithm == TWO_STAGE_COMP) {
|
||||||
int zsize = pDataCol->bytes * pBlock->numOfRows + COMP_OVERFLOW_BYTES;
|
int zsize = pDataCol->bytes * pBlock->numOfRows + tLenBitmap + 2 * COMP_OVERFLOW_BYTES;
|
||||||
if (tsdbMakeRoom((void **)(&TSDB_READ_COMP_BUF(pReadh)), zsize) < 0) return -1;
|
if (tsdbMakeRoom((void **)(&TSDB_READ_COMP_BUF(pReadh)), zsize) < 0) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tsdbCheckAndDecodeColumnData(pDataCol, POINTER_SHIFT(pBlockData, tsize + toffset), tlen, pBlock->algorithm,
|
if (tsdbCheckAndDecodeColumnData(pDataCol, POINTER_SHIFT(pBlockData, tsize + toffset), tlen, pBlockCol->blen,
|
||||||
pBlock->numOfRows, tBitmaps, tLenBitmap, pDataCols->maxPoints, TSDB_READ_COMP_BUF(pReadh),
|
pBlock->algorithm, pBlock->numOfRows, tLenBitmap, pDataCols->maxPoints,
|
||||||
(int)taosTSizeof(TSDB_READ_COMP_BUF(pReadh))) < 0) {
|
TSDB_READ_COMP_BUF(pReadh), (int)taosTSizeof(TSDB_READ_COMP_BUF(pReadh))) < 0) {
|
||||||
tsdbError("vgId:%d file %s is broken at column %d block offset %" PRId64 " column offset %u",
|
tsdbError("vgId:%d file %s is broken at column %d block offset %" PRId64 " column offset %u",
|
||||||
TSDB_READ_REPO_ID(pReadh), TSDB_FILE_FULL_NAME(pDFile), tcolId, (int64_t)pBlock->offset, toffset);
|
TSDB_READ_REPO_ID(pReadh), TSDB_FILE_FULL_NAME(pDFile), tcolId, (int64_t)pBlock->offset, toffset);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -609,9 +611,8 @@ static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDat
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsdbCheckAndDecodeColumnData(SDataCol *pDataCol, void *content, int32_t len, int8_t comp, int numOfRows,
|
static int tsdbCheckAndDecodeColumnData(SDataCol *pDataCol, void *content, int32_t len, int32_t bitmapLen, int8_t comp,
|
||||||
int numOfBitmaps, int lenOfBitmaps, int maxPoints, char *buffer,
|
int numOfRows, int numOfBitmaps, int maxPoints, char *buffer, int bufferSize) {
|
||||||
int bufferSize) {
|
|
||||||
if (!taosCheckChecksumWhole((uint8_t *)content, len)) {
|
if (!taosCheckChecksumWhole((uint8_t *)content, len)) {
|
||||||
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
|
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -623,21 +624,41 @@ static int tsdbCheckAndDecodeColumnData(SDataCol *pDataCol, void *content, int32
|
||||||
if (comp) {
|
if (comp) {
|
||||||
// Need to decompress
|
// Need to decompress
|
||||||
int tlen =
|
int tlen =
|
||||||
(*(tDataTypes[pDataCol->type].decompFunc))(content, len - sizeof(TSCKSUM), numOfRows + numOfBitmaps,
|
(*(tDataTypes[pDataCol->type].decompFunc))(content, len - bitmapLen - sizeof(TSCKSUM), numOfRows,
|
||||||
pDataCol->pData, pDataCol->spaceSize, comp, buffer, bufferSize);
|
pDataCol->pData, pDataCol->spaceSize, comp, buffer, bufferSize);
|
||||||
if (tlen <= 0) {
|
if (tlen <= 0) {
|
||||||
tsdbError("Failed to decompress column, file corrupted, len:%d comp:%d numOfRows:%d maxPoints:%d bufferSize:%d",
|
tsdbError(
|
||||||
len, comp, numOfRows, maxPoints, bufferSize);
|
"Failed to decompress column data, file corrupted, len:%d comp:%d numOfRows:%d maxPoints:%d bufferSize:%d",
|
||||||
|
(int32_t)(len - bitmapLen - sizeof(TSCKSUM)), comp, numOfRows, maxPoints, bufferSize);
|
||||||
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
|
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pDataCol->len = tlen;
|
pDataCol->len = tlen;
|
||||||
|
|
||||||
|
if (numOfBitmaps > 0) {
|
||||||
|
tlen = tsDecompressTinyint(POINTER_SHIFT(content, len - bitmapLen - sizeof(TSCKSUM)), bitmapLen, numOfBitmaps,
|
||||||
|
pDataCol->pBitmap, pDataCol->spaceSize, comp, buffer, bufferSize);
|
||||||
|
if (tlen <= 0) {
|
||||||
|
tsdbError(
|
||||||
|
"Failed to decompress column bitmap, file corrupted, len:%d comp:%d numOfRows:%d maxPoints:%d "
|
||||||
|
"bufferSize:%d",
|
||||||
|
bitmapLen, comp, numOfBitmaps, maxPoints, bufferSize);
|
||||||
|
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// pDataCol->blen = tlen;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// No need to decompress, just memcpy it
|
// No need to decompress, just memcpy it
|
||||||
pDataCol->len = len - sizeof(TSCKSUM);
|
pDataCol->len = len - bitmapLen - sizeof(TSCKSUM);
|
||||||
memcpy(pDataCol->pData, content, pDataCol->len);
|
memcpy(pDataCol->pData, content, pDataCol->len);
|
||||||
|
if (numOfBitmaps > 0) {
|
||||||
|
// pDataCol->blen = bitmapLen;
|
||||||
|
memcpy(pDataCol->pBitmap, POINTER_SHIFT(content, len - bitmapLen - sizeof(TSCKSUM)), bitmapLen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (lenOfBitmaps > 0) {
|
if (lenOfBitmaps > 0) {
|
||||||
pDataCol->len -= lenOfBitmaps;
|
pDataCol->len -= lenOfBitmaps;
|
||||||
|
|
||||||
|
@ -653,7 +674,10 @@ static int tsdbCheckAndDecodeColumnData(SDataCol *pDataCol, void *content, int32
|
||||||
} else if (IS_VAR_DATA_TYPE(pDataCol->type)) {
|
} else if (IS_VAR_DATA_TYPE(pDataCol->type)) {
|
||||||
dataColSetOffset(pDataCol, numOfRows);
|
dataColSetOffset(pDataCol, numOfRows);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
if (IS_VAR_DATA_TYPE(pDataCol->type)) {
|
||||||
|
dataColSetOffset(pDataCol, numOfRows);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,14 +764,16 @@ static int tsdbLoadBlockDataColsImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *
|
||||||
static int tsdbLoadColData(SReadH *pReadh, SDFile *pDFile, SBlock *pBlock, SBlockCol *pBlockCol, SDataCol *pDataCol) {
|
static int tsdbLoadColData(SReadH *pReadh, SDFile *pDFile, SBlock *pBlock, SBlockCol *pBlockCol, SDataCol *pDataCol) {
|
||||||
ASSERT(pDataCol->colId == pBlockCol->colId);
|
ASSERT(pDataCol->colId == pBlockCol->colId);
|
||||||
|
|
||||||
STsdb * pRepo = TSDB_READ_REPO(pReadh);
|
STsdb *pRepo = TSDB_READ_REPO(pReadh);
|
||||||
STsdbCfg *pCfg = REPO_CFG(pRepo);
|
STsdbCfg *pCfg = REPO_CFG(pRepo);
|
||||||
|
|
||||||
int nBitmaps = (int)TD_BITMAP_BYTES(pBlock->numOfRows);
|
int nBitmaps = (int)TD_BITMAP_BYTES(pBlock->numOfRows);
|
||||||
int32_t tBitmaps = 0;
|
// int32_t tBitmaps = 0;
|
||||||
int32_t tLenBitmap = 0;
|
int32_t tLenBitmap = 0;
|
||||||
|
|
||||||
if (!TD_COL_ROWS_NORM(pBlockCol)) {
|
if (!TD_COL_ROWS_NORM(pBlockCol)) {
|
||||||
|
tLenBitmap = nBitmaps;
|
||||||
|
#if 0
|
||||||
if (IS_VAR_DATA_TYPE(pDataCol->type)) {
|
if (IS_VAR_DATA_TYPE(pDataCol->type)) {
|
||||||
tBitmaps = nBitmaps;
|
tBitmaps = nBitmaps;
|
||||||
tLenBitmap = tBitmaps;
|
tLenBitmap = tBitmaps;
|
||||||
|
@ -755,9 +781,10 @@ static int tsdbLoadColData(SReadH *pReadh, SDFile *pDFile, SBlock *pBlock, SBloc
|
||||||
tBitmaps = (int32_t)ceil((double)nBitmaps / TYPE_BYTES[pDataCol->type]);
|
tBitmaps = (int32_t)ceil((double)nBitmaps / TYPE_BYTES[pDataCol->type]);
|
||||||
tLenBitmap = tBitmaps * TYPE_BYTES[pDataCol->type];
|
tLenBitmap = tBitmaps * TYPE_BYTES[pDataCol->type];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int tsize = pDataCol->bytes * pBlock->numOfRows + tLenBitmap + COMP_OVERFLOW_BYTES;
|
int tsize = pDataCol->bytes * pBlock->numOfRows + tLenBitmap + 2 * COMP_OVERFLOW_BYTES;
|
||||||
|
|
||||||
if (tsdbMakeRoom((void **)(&TSDB_READ_BUF(pReadh)), pBlockCol->len) < 0) return -1;
|
if (tsdbMakeRoom((void **)(&TSDB_READ_BUF(pReadh)), pBlockCol->len) < 0) return -1;
|
||||||
if (tsdbMakeRoom((void **)(&TSDB_READ_COMP_BUF(pReadh)), tsize) < 0) return -1;
|
if (tsdbMakeRoom((void **)(&TSDB_READ_COMP_BUF(pReadh)), tsize) < 0) return -1;
|
||||||
|
@ -785,8 +812,8 @@ static int tsdbLoadColData(SReadH *pReadh, SDFile *pDFile, SBlock *pBlock, SBloc
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tsdbCheckAndDecodeColumnData(pDataCol, pReadh->pBuf, pBlockCol->len, pBlock->algorithm, pBlock->numOfRows,
|
if (tsdbCheckAndDecodeColumnData(pDataCol, pReadh->pBuf, pBlockCol->len, pBlockCol->blen, pBlock->algorithm,
|
||||||
tBitmaps, tLenBitmap, pCfg->maxRowsPerFileBlock, pReadh->pCBuf,
|
pBlock->numOfRows, tLenBitmap, pCfg->maxRowsPerFileBlock, pReadh->pCBuf,
|
||||||
(int32_t)taosTSizeof(pReadh->pCBuf)) < 0) {
|
(int32_t)taosTSizeof(pReadh->pCBuf)) < 0) {
|
||||||
tsdbError("vgId:%d file %s is broken at column %d offset %" PRId64, REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile),
|
tsdbError("vgId:%d file %s is broken at column %d offset %" PRId64, REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pDFile),
|
||||||
pBlockCol->colId, offset);
|
pBlockCol->colId, offset);
|
||||||
|
|
|
@ -26,38 +26,54 @@ extern "C" {
|
||||||
#define EXPLAIN_MAX_GROUP_NUM 100
|
#define EXPLAIN_MAX_GROUP_NUM 100
|
||||||
|
|
||||||
//newline area
|
//newline area
|
||||||
#define EXPLAIN_TAG_SCAN_FORMAT "Tag Scan on %s columns=%d width=%d"
|
#define EXPLAIN_TAG_SCAN_FORMAT "Tag Scan on %s"
|
||||||
#define EXPLAIN_TBL_SCAN_FORMAT "Table Scan on %s columns=%d width=%d"
|
#define EXPLAIN_TBL_SCAN_FORMAT "Table Scan on %s"
|
||||||
#define EXPLAIN_SYSTBL_SCAN_FORMAT "System Table Scan on %s columns=%d width=%d"
|
#define EXPLAIN_SYSTBL_SCAN_FORMAT "System Table Scan on %s"
|
||||||
#define EXPLAIN_PROJECTION_FORMAT "Projection columns=%d width=%d"
|
#define EXPLAIN_PROJECTION_FORMAT "Projection"
|
||||||
#define EXPLAIN_JOIN_FORMAT "%s between %d tables width=%d"
|
#define EXPLAIN_JOIN_FORMAT "%s"
|
||||||
#define EXPLAIN_AGG_FORMAT "Aggragate functions=%d"
|
#define EXPLAIN_AGG_FORMAT "Aggragate"
|
||||||
#define EXPLAIN_EXCHANGE_FORMAT "Data Exchange %d:1 width=%d"
|
#define EXPLAIN_EXCHANGE_FORMAT "Data Exchange %d:1"
|
||||||
#define EXPLAIN_SORT_FORMAT "Sort on %d Column(s) width=%d"
|
#define EXPLAIN_SORT_FORMAT "Sort"
|
||||||
#define EXPLAIN_INTERVAL_FORMAT "Interval on Column %s functions=%d interval=%" PRId64 "%c offset=%" PRId64 "%c sliding=%" PRId64 "%c width=%d"
|
#define EXPLAIN_INTERVAL_FORMAT "Interval on Column %s"
|
||||||
#define EXPLAIN_SESSION_FORMAT "Session gap=%" PRId64 " functions=%d width=%d"
|
#define EXPLAIN_SESSION_FORMAT "Session"
|
||||||
#define EXPLAIN_ORDER_FORMAT "Order: %s"
|
#define EXPLAIN_ORDER_FORMAT "Order: %s"
|
||||||
#define EXPLAIN_FILTER_FORMAT "Filter: "
|
#define EXPLAIN_FILTER_FORMAT "Filter: "
|
||||||
#define EXPLAIN_FILL_FORMAT "Fill: %s"
|
#define EXPLAIN_FILL_FORMAT "Fill: %s"
|
||||||
#define EXPLAIN_ON_CONDITIONS_FORMAT "Join Cond: "
|
#define EXPLAIN_ON_CONDITIONS_FORMAT "Join Cond: "
|
||||||
#define EXPLAIN_TIMERANGE_FORMAT "Time Range: [%" PRId64 ", %" PRId64 "]"
|
#define EXPLAIN_TIMERANGE_FORMAT "Time Range: [%" PRId64 ", %" PRId64 "]"
|
||||||
|
#define EXPLAIN_OUTPUT_FORMAT "Output: "
|
||||||
|
#define EXPLAIN_TIME_WINDOWS_FORMAT "Time Window: interval=%" PRId64 "%c offset=%" PRId64 "%c sliding=%" PRId64 "%c"
|
||||||
|
#define EXPLAIN_WINDOW_FORMAT "Window: gap=%" PRId64
|
||||||
|
|
||||||
//append area
|
//append area
|
||||||
#define EXPLAIN_GROUPS_FORMAT " groups=%d"
|
#define EXPLAIN_LEFT_PARENTHESIS_FORMAT " ("
|
||||||
#define EXPLAIN_WIDTH_FORMAT " width=%d"
|
#define EXPLAIN_RIGHT_PARENTHESIS_FORMAT ")"
|
||||||
#define EXPLAIN_LOOPS_FORMAT " loops=%d"
|
#define EXPLAIN_BLANK_FORMAT " "
|
||||||
#define EXPLAIN_REVERSE_FORMAT " reverse=%d"
|
#define EXPLAIN_COST_FORMAT "cost=%.2f..%.2f"
|
||||||
|
#define EXPLAIN_ROWS_FORMAT "rows=%" PRIu64
|
||||||
|
#define EXPLAIN_COLUMNS_FORMAT "columns=%d"
|
||||||
|
#define EXPLAIN_WIDTH_FORMAT "width=%d"
|
||||||
|
#define EXPLAIN_GROUPS_FORMAT "groups=%d"
|
||||||
|
#define EXPLAIN_WIDTH_FORMAT "width=%d"
|
||||||
|
#define EXPLAIN_LOOPS_FORMAT "loops=%d"
|
||||||
|
#define EXPLAIN_REVERSE_FORMAT "reverse=%d"
|
||||||
|
#define EXPLAIN_FUNCTIONS_FORMAT "functions=%d"
|
||||||
|
#define EXPLAIN_EXECINFO_FORMAT "cost=%" PRIu64 "..%" PRIu64 " rows=%" PRIu64
|
||||||
|
|
||||||
typedef struct SExplainGroup {
|
typedef struct SExplainGroup {
|
||||||
int32_t nodeNum;
|
int32_t nodeNum;
|
||||||
|
int32_t physiPlanExecNum;
|
||||||
|
int32_t physiPlanNum;
|
||||||
|
int32_t physiPlanExecIdx;
|
||||||
|
SRWLatch lock;
|
||||||
SSubplan *plan;
|
SSubplan *plan;
|
||||||
void *execInfo; //TODO
|
SArray *nodeExecInfo; //Array<SExplainRsp>
|
||||||
} SExplainGroup;
|
} SExplainGroup;
|
||||||
|
|
||||||
typedef struct SExplainResNode {
|
typedef struct SExplainResNode {
|
||||||
SNodeList* pChildren;
|
SNodeList* pChildren;
|
||||||
SPhysiNode* pNode;
|
SPhysiNode* pNode;
|
||||||
void* pExecInfo;
|
SArray* pExecInfo; // Array<SExplainExecInfo>
|
||||||
} SExplainResNode;
|
} SExplainResNode;
|
||||||
|
|
||||||
typedef struct SQueryExplainRowInfo {
|
typedef struct SQueryExplainRowInfo {
|
||||||
|
@ -67,11 +83,21 @@ typedef struct SQueryExplainRowInfo {
|
||||||
} SQueryExplainRowInfo;
|
} SQueryExplainRowInfo;
|
||||||
|
|
||||||
typedef struct SExplainCtx {
|
typedef struct SExplainCtx {
|
||||||
int32_t totalSize;
|
EExplainMode mode;
|
||||||
bool verbose;
|
double ratio;
|
||||||
char *tbuf;
|
bool verbose;
|
||||||
SArray *rows;
|
|
||||||
SHashObj *groupHash;
|
SRWLatch lock;
|
||||||
|
int32_t rootGroupId;
|
||||||
|
int32_t dataSize;
|
||||||
|
bool execDone;
|
||||||
|
int64_t reqStartTs;
|
||||||
|
int64_t jobStartTs;
|
||||||
|
int64_t jobDoneTs;
|
||||||
|
char *tbuf;
|
||||||
|
SArray *rows;
|
||||||
|
int32_t groupDoneNum;
|
||||||
|
SHashObj *groupHash; // Hash<SExplainGroup>
|
||||||
} SExplainCtx;
|
} SExplainCtx;
|
||||||
|
|
||||||
#define EXPLAIN_ORDER_STRING(_order) ((TSDB_ORDER_ASC == _order) ? "Ascending" : "Descending")
|
#define EXPLAIN_ORDER_STRING(_order) ((TSDB_ORDER_ASC == _order) ? "Ascending" : "Descending")
|
||||||
|
|
|
@ -17,44 +17,61 @@
|
||||||
#include "plannodes.h"
|
#include "plannodes.h"
|
||||||
#include "commandInt.h"
|
#include "commandInt.h"
|
||||||
|
|
||||||
int32_t qGenerateExplainResNode(SPhysiNode *pNode, void *pExecInfo, SExplainResNode **pRes);
|
int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pRes);
|
||||||
int32_t qAppendTaskExplainResRows(void *pCtx, int32_t groupId, int32_t level);
|
int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level);
|
||||||
|
|
||||||
|
|
||||||
void qFreeExplainResTree(SExplainResNode *res) {
|
void qExplainFreeResNode(SExplainResNode *resNode) {
|
||||||
if (NULL == res) {
|
if (NULL == resNode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
taosMemoryFreeClear(res->pExecInfo);
|
taosMemoryFreeClear(resNode->pExecInfo);
|
||||||
|
|
||||||
SNode* node = NULL;
|
SNode* node = NULL;
|
||||||
FOREACH(node, res->pChildren) {
|
FOREACH(node, resNode->pChildren) {
|
||||||
qFreeExplainResTree((SExplainResNode *)node);
|
qExplainFreeResNode((SExplainResNode *)node);
|
||||||
}
|
}
|
||||||
nodesClearList(res->pChildren);
|
nodesClearList(resNode->pChildren);
|
||||||
|
|
||||||
taosMemoryFreeClear(res);
|
taosMemoryFreeClear(resNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qFreeExplainCtx(void *ctx) {
|
void qExplainFreeCtx(SExplainCtx *pCtx) {
|
||||||
if (NULL == ctx) {
|
if (NULL == pCtx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SExplainCtx *pCtx = (SExplainCtx *)ctx;
|
|
||||||
int32_t rowSize = taosArrayGetSize(pCtx->rows);
|
int32_t rowSize = taosArrayGetSize(pCtx->rows);
|
||||||
for (int32_t i = 0; i < rowSize; ++i) {
|
for (int32_t i = 0; i < rowSize; ++i) {
|
||||||
SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
|
SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
|
||||||
taosMemoryFreeClear(row->buf);
|
taosMemoryFreeClear(row->buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EXPLAIN_MODE_ANALYZE == pCtx->mode && pCtx->groupHash) {
|
||||||
|
void *pIter = taosHashIterate(pCtx->groupHash, NULL);
|
||||||
|
while (pIter) {
|
||||||
|
SExplainGroup *group = (SExplainGroup *)pIter;
|
||||||
|
if (NULL == group->nodeExecInfo) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t num = taosArrayGetSize(group->nodeExecInfo);
|
||||||
|
for (int32_t i = 0; i < num; ++i) {
|
||||||
|
SExplainRsp *rsp = taosArrayGet(group->nodeExecInfo, i);
|
||||||
|
taosMemoryFreeClear(rsp->subplanInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
pIter = taosHashIterate(pCtx->groupHash, pIter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
taosHashCleanup(pCtx->groupHash);
|
taosHashCleanup(pCtx->groupHash);
|
||||||
taosArrayDestroy(pCtx->rows);
|
taosArrayDestroy(pCtx->rows);
|
||||||
taosMemoryFree(pCtx);
|
taosMemoryFree(pCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t qInitExplainCtx(void **pCtx, SHashObj *groupHash, bool verbose) {
|
int32_t qExplainInitCtx(SExplainCtx **pCtx, SHashObj *groupHash, bool verbose, double ratio, EExplainMode mode) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
SExplainCtx *ctx = taosMemoryCalloc(1, sizeof(SExplainCtx));
|
SExplainCtx *ctx = taosMemoryCalloc(1, sizeof(SExplainCtx));
|
||||||
if (NULL == ctx) {
|
if (NULL == ctx) {
|
||||||
|
@ -74,7 +91,9 @@ int32_t qInitExplainCtx(void **pCtx, SHashObj *groupHash, bool verbose) {
|
||||||
QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->mode = mode;
|
||||||
ctx->verbose = verbose;
|
ctx->verbose = verbose;
|
||||||
|
ctx->ratio = ratio;
|
||||||
ctx->tbuf = tbuf;
|
ctx->tbuf = tbuf;
|
||||||
ctx->rows = rows;
|
ctx->rows = rows;
|
||||||
ctx->groupHash = groupHash;
|
ctx->groupHash = groupHash;
|
||||||
|
@ -92,35 +111,7 @@ _return:
|
||||||
QRY_RET(code);
|
QRY_RET(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNodeList **pChildren) {
|
||||||
char *qFillModeString(EFillMode mode) {
|
|
||||||
switch (mode) {
|
|
||||||
case FILL_MODE_NONE:
|
|
||||||
return "none";
|
|
||||||
case FILL_MODE_VALUE:
|
|
||||||
return "value";
|
|
||||||
case FILL_MODE_PREV:
|
|
||||||
return "prev";
|
|
||||||
case FILL_MODE_NULL:
|
|
||||||
return "null";
|
|
||||||
case FILL_MODE_LINEAR:
|
|
||||||
return "linear";
|
|
||||||
case FILL_MODE_NEXT:
|
|
||||||
return "next";
|
|
||||||
default:
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char *qGetNameFromColumnNode(SNode *pNode) {
|
|
||||||
if (NULL == pNode || QUERY_NODE_COLUMN != pNode->type) {
|
|
||||||
return "NULL";
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((SColumnNode *)pNode)->colName;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t qGenerateExplainResChildren(SPhysiNode *pNode, void *pExecInfo, SNodeList **pChildren) {
|
|
||||||
int32_t tlen = 0;
|
int32_t tlen = 0;
|
||||||
SNodeList *pPhysiChildren = NULL;
|
SNodeList *pPhysiChildren = NULL;
|
||||||
|
|
||||||
|
@ -192,52 +183,119 @@ int32_t qGenerateExplainResChildren(SPhysiNode *pNode, void *pExecInfo, SNodeLis
|
||||||
SNode* node = NULL;
|
SNode* node = NULL;
|
||||||
SExplainResNode *pResNode = NULL;
|
SExplainResNode *pResNode = NULL;
|
||||||
FOREACH(node, pPhysiChildren) {
|
FOREACH(node, pPhysiChildren) {
|
||||||
QRY_ERR_RET(qGenerateExplainResNode((SPhysiNode *)node, pExecInfo, &pResNode));
|
QRY_ERR_RET(qExplainGenerateResNode((SPhysiNode *)node, group, &pResNode));
|
||||||
QRY_ERR_RET(nodesListAppend(*pChildren, pResNode));
|
QRY_ERR_RET(nodesListAppend(*pChildren, pResNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t qGenerateExplainResNode(SPhysiNode *pNode, void *pExecInfo, SExplainResNode **pRes) {
|
int32_t qExplainGenerateResNodeExecInfo(SArray **pExecInfo, SExplainGroup *group) {
|
||||||
|
*pExecInfo = taosArrayInit(group->nodeNum, sizeof(SExplainExecInfo));
|
||||||
|
if (NULL == (*pExecInfo)) {
|
||||||
|
qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
|
||||||
|
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
SExplainRsp *rsp = NULL;
|
||||||
|
for (int32_t i = 0; i < group->nodeNum; ++i) {
|
||||||
|
rsp = taosArrayGet(group->nodeExecInfo, i);
|
||||||
|
if (group->physiPlanExecIdx >= rsp->numOfPlans) {
|
||||||
|
qError("physiPlanIdx %d exceed plan num %d", group->physiPlanExecIdx, rsp->numOfPlans);
|
||||||
|
return TSDB_CODE_QRY_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArrayPush(*pExecInfo, rsp->subplanInfo + group->physiPlanExecIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
++group->physiPlanExecIdx;
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pResNode) {
|
||||||
if (NULL == pNode) {
|
if (NULL == pNode) {
|
||||||
*pRes = NULL;
|
*pResNode = NULL;
|
||||||
qError("physical node is NULL");
|
qError("physical node is NULL");
|
||||||
return TSDB_CODE_QRY_APP_ERROR;
|
return TSDB_CODE_QRY_APP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
SExplainResNode *res = taosMemoryCalloc(1, sizeof(SExplainResNode));
|
SExplainResNode *resNode = taosMemoryCalloc(1, sizeof(SExplainResNode));
|
||||||
if (NULL == res) {
|
if (NULL == resNode) {
|
||||||
qError("calloc SPhysiNodeExplainRes failed");
|
qError("calloc SPhysiNodeExplainRes failed");
|
||||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
res->pNode = pNode;
|
resNode->pNode = pNode;
|
||||||
res->pExecInfo = pExecInfo;
|
|
||||||
QRY_ERR_JRET(qGenerateExplainResChildren(pNode, pExecInfo, &res->pChildren));
|
|
||||||
|
|
||||||
*pRes = res;
|
if (group->nodeExecInfo) {
|
||||||
|
QRY_ERR_JRET(qExplainGenerateResNodeExecInfo(&resNode->pExecInfo, group));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRY_ERR_JRET(qExplainGenerateResChildren(pNode, group, &resNode->pChildren));
|
||||||
|
|
||||||
|
++group->physiPlanNum;
|
||||||
|
|
||||||
|
*pResNode = resNode;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
_return:
|
_return:
|
||||||
|
|
||||||
qFreeExplainResTree(res);
|
qExplainFreeResNode(resNode);
|
||||||
|
|
||||||
QRY_RET(code);
|
QRY_RET(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t qExplainBufAppendExecInfo(void *pExecInfo, char *tbuf, int32_t *len) {
|
int32_t qExplainBufAppendExecInfo(SArray *pExecInfo, char *tbuf, int32_t *len) {
|
||||||
int32_t tlen = *len;
|
int32_t tlen = *len;
|
||||||
|
int32_t nodeNum = taosArrayGetSize(pExecInfo);
|
||||||
|
SExplainExecInfo maxExecInfo = {0};
|
||||||
|
|
||||||
EXPLAIN_ROW_APPEND("(exec info here)");
|
for (int32_t i = 0; i < nodeNum; ++i) {
|
||||||
|
SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i);
|
||||||
|
if (execInfo->startupCost > maxExecInfo.startupCost) {
|
||||||
|
maxExecInfo.startupCost = execInfo->startupCost;
|
||||||
|
}
|
||||||
|
if (execInfo->totalCost > maxExecInfo.totalCost) {
|
||||||
|
maxExecInfo.totalCost = execInfo->totalCost;
|
||||||
|
}
|
||||||
|
if (execInfo->numOfRows > maxExecInfo.numOfRows) {
|
||||||
|
maxExecInfo.numOfRows = execInfo->numOfRows;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_EXECINFO_FORMAT, maxExecInfo.startupCost, maxExecInfo.totalCost, maxExecInfo.numOfRows);
|
||||||
|
|
||||||
*len = tlen;
|
*len = tlen;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t qExplainBufAppendVerboseExecInfo(SArray *pExecInfo, char *tbuf, int32_t *len) {
|
||||||
|
int32_t tlen = 0;
|
||||||
|
bool gotVerbose = false;
|
||||||
|
int32_t nodeNum = taosArrayGetSize(pExecInfo);
|
||||||
|
SExplainExecInfo maxExecInfo = {0};
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < nodeNum; ++i) {
|
||||||
|
SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i);
|
||||||
|
if (execInfo->verboseInfo) {
|
||||||
|
gotVerbose = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gotVerbose) {
|
||||||
|
EXPLAIN_ROW_APPEND("exec verbose info");
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = tlen;
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t level) {
|
int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t level) {
|
||||||
SQueryExplainRowInfo row = {0};
|
SQueryExplainRowInfo row = {0};
|
||||||
row.buf = taosMemoryMalloc(len);
|
row.buf = taosMemoryMalloc(len);
|
||||||
|
@ -249,7 +307,7 @@ int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t
|
||||||
memcpy(row.buf, tbuf, len);
|
memcpy(row.buf, tbuf, len);
|
||||||
row.level = level;
|
row.level = level;
|
||||||
row.len = len;
|
row.len = len;
|
||||||
ctx->totalSize += len;
|
ctx->dataSize += len;
|
||||||
|
|
||||||
if (NULL == taosArrayPush(ctx->rows, &row)) {
|
if (NULL == taosArrayPush(ctx->rows, &row)) {
|
||||||
qError("taosArrayPush row to explain res rows failed");
|
qError("taosArrayPush row to explain res rows failed");
|
||||||
|
@ -275,39 +333,77 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
||||||
switch (pNode->type) {
|
switch (pNode->type) {
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: {
|
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: {
|
||||||
STagScanPhysiNode *pTagScanNode = (STagScanPhysiNode *)pNode;
|
STagScanPhysiNode *pTagScanNode = (STagScanPhysiNode *)pNode;
|
||||||
EXPLAIN_ROW_NEW(level, EXPLAIN_TAG_SCAN_FORMAT, pTagScanNode->tableName.tname, pTagScanNode->pScanCols->length, pTagScanNode->node.pOutputDataBlockDesc->outputRowSize);
|
EXPLAIN_ROW_NEW(level, EXPLAIN_TAG_SCAN_FORMAT, pTagScanNode->tableName.tname);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||||
if (pResNode->pExecInfo) {
|
if (pResNode->pExecInfo) {
|
||||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||||
}
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTagScanNode->pScanCols->length);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
EXPLAIN_ROW_APPEND(EXPLAIN_LOOPS_FORMAT, pTagScanNode->count);
|
EXPLAIN_ROW_APPEND(EXPLAIN_LOOPS_FORMAT, pTagScanNode->count);
|
||||||
if (pTagScanNode->reverse) {
|
if (pTagScanNode->reverse) {
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
EXPLAIN_ROW_APPEND(EXPLAIN_REVERSE_FORMAT, pTagScanNode->reverse);
|
EXPLAIN_ROW_APPEND(EXPLAIN_REVERSE_FORMAT, pTagScanNode->reverse);
|
||||||
}
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pTagScanNode->node.pOutputDataBlockDesc->pSlots));
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pTagScanNode->order));
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pTagScanNode->order));
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
|
if (pResNode->pExecInfo) {
|
||||||
|
QRY_ERR_RET(qExplainBufAppendVerboseExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||||
|
if (tlen) {
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
|
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:{
|
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:{
|
||||||
STableScanPhysiNode *pTblScanNode = (STableScanPhysiNode *)pNode;
|
STableScanPhysiNode *pTblScanNode = (STableScanPhysiNode *)pNode;
|
||||||
EXPLAIN_ROW_NEW(level, EXPLAIN_TBL_SCAN_FORMAT, pTblScanNode->scan.tableName.tname, pTblScanNode->scan.pScanCols->length, pTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
|
EXPLAIN_ROW_NEW(level, EXPLAIN_TBL_SCAN_FORMAT, pTblScanNode->scan.tableName.tname);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||||
if (pResNode->pExecInfo) {
|
if (pResNode->pExecInfo) {
|
||||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||||
}
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTblScanNode->scan.pScanCols->length);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
EXPLAIN_ROW_APPEND(EXPLAIN_LOOPS_FORMAT, pTblScanNode->scan.count);
|
EXPLAIN_ROW_APPEND(EXPLAIN_LOOPS_FORMAT, pTblScanNode->scan.count);
|
||||||
if (pTblScanNode->scan.reverse) {
|
if (pTblScanNode->scan.reverse) {
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
EXPLAIN_ROW_APPEND(EXPLAIN_REVERSE_FORMAT, pTblScanNode->scan.reverse);
|
EXPLAIN_ROW_APPEND(EXPLAIN_REVERSE_FORMAT, pTblScanNode->scan.reverse);
|
||||||
}
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pTblScanNode->scan.order));
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pTblScanNode->scan.order));
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
@ -327,18 +423,33 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
||||||
}
|
}
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:{
|
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:{
|
||||||
SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode;
|
SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode;
|
||||||
EXPLAIN_ROW_NEW(level, EXPLAIN_SYSTBL_SCAN_FORMAT, pSTblScanNode->scan.tableName.tname, pSTblScanNode->scan.pScanCols->length, pSTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
|
EXPLAIN_ROW_NEW(level, EXPLAIN_SYSTBL_SCAN_FORMAT, pSTblScanNode->scan.tableName.tname);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||||
if (pResNode->pExecInfo) {
|
if (pResNode->pExecInfo) {
|
||||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||||
}
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSTblScanNode->scan.pScanCols->length);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
EXPLAIN_ROW_APPEND(EXPLAIN_LOOPS_FORMAT, pSTblScanNode->scan.count);
|
EXPLAIN_ROW_APPEND(EXPLAIN_LOOPS_FORMAT, pSTblScanNode->scan.count);
|
||||||
if (pSTblScanNode->scan.reverse) {
|
if (pSTblScanNode->scan.reverse) {
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
EXPLAIN_ROW_APPEND(EXPLAIN_REVERSE_FORMAT, pSTblScanNode->scan.reverse);
|
EXPLAIN_ROW_APPEND(EXPLAIN_REVERSE_FORMAT, pSTblScanNode->scan.reverse);
|
||||||
}
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pSTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pSTblScanNode->scan.order));
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ORDER_FORMAT, EXPLAIN_ORDER_STRING(pSTblScanNode->scan.order));
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
@ -355,14 +466,27 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
||||||
}
|
}
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:{
|
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:{
|
||||||
SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode;
|
SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode;
|
||||||
EXPLAIN_ROW_NEW(level, EXPLAIN_PROJECTION_FORMAT, pPrjNode->pProjections->length, pPrjNode->node.pOutputDataBlockDesc->outputRowSize);
|
EXPLAIN_ROW_NEW(level, EXPLAIN_PROJECTION_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||||
if (pResNode->pExecInfo) {
|
if (pResNode->pExecInfo) {
|
||||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||||
}
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pPrjNode->pProjections->length);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pPrjNode->node.pOutputDataBlockDesc->pSlots));
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
if (pPrjNode->node.pConditions) {
|
if (pPrjNode->node.pConditions) {
|
||||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||||
QRY_ERR_RET(nodesNodeToSQL(pPrjNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
QRY_ERR_RET(nodesNodeToSQL(pPrjNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||||
|
@ -374,14 +498,27 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
||||||
}
|
}
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_JOIN:{
|
case QUERY_NODE_PHYSICAL_PLAN_JOIN:{
|
||||||
SJoinPhysiNode *pJoinNode = (SJoinPhysiNode *)pNode;
|
SJoinPhysiNode *pJoinNode = (SJoinPhysiNode *)pNode;
|
||||||
EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, EXPLAIN_JOIN_STRING(pJoinNode->joinType), pJoinNode->pTargets->length, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
|
EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, EXPLAIN_JOIN_STRING(pJoinNode->joinType));
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||||
if (pResNode->pExecInfo) {
|
if (pResNode->pExecInfo) {
|
||||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||||
}
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
if (pJoinNode->node.pConditions) {
|
if (pJoinNode->node.pConditions) {
|
||||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||||
QRY_ERR_RET(nodesNodeToSQL(pJoinNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
QRY_ERR_RET(nodesNodeToSQL(pJoinNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||||
|
@ -398,19 +535,31 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
||||||
}
|
}
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_AGG:{
|
case QUERY_NODE_PHYSICAL_PLAN_AGG:{
|
||||||
SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
|
SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
|
||||||
EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT, pAggNode->pAggFuncs->length);
|
EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT);
|
||||||
if (pAggNode->pGroupKeys) {
|
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||||
EXPLAIN_ROW_APPEND(EXPLAIN_GROUPS_FORMAT, pAggNode->pGroupKeys->length);
|
|
||||||
}
|
|
||||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->outputRowSize);
|
|
||||||
|
|
||||||
if (pResNode->pExecInfo) {
|
if (pResNode->pExecInfo) {
|
||||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pAggNode->pAggFuncs->length);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||||
|
if (pAggNode->pGroupKeys) {
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_GROUPS_FORMAT, pAggNode->pGroupKeys->length);
|
||||||
}
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pAggNode->node.pOutputDataBlockDesc->pSlots));
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
if (pAggNode->node.pConditions) {
|
if (pAggNode->node.pConditions) {
|
||||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||||
QRY_ERR_RET(nodesNodeToSQL(pAggNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
QRY_ERR_RET(nodesNodeToSQL(pAggNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||||
|
@ -428,14 +577,25 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
||||||
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPLAIN_ROW_NEW(level, EXPLAIN_EXCHANGE_FORMAT, group->nodeNum, pExchNode->node.pOutputDataBlockDesc->outputRowSize);
|
EXPLAIN_ROW_NEW(level, EXPLAIN_EXCHANGE_FORMAT, group->nodeNum);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||||
if (pResNode->pExecInfo) {
|
if (pResNode->pExecInfo) {
|
||||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||||
}
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pExchNode->node.pOutputDataBlockDesc->pSlots));
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
if (pExchNode->node.pConditions) {
|
if (pExchNode->node.pConditions) {
|
||||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||||
QRY_ERR_RET(nodesNodeToSQL(pExchNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
QRY_ERR_RET(nodesNodeToSQL(pExchNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||||
|
@ -444,19 +604,33 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QRY_ERR_RET(qAppendTaskExplainResRows(ctx, pExchNode->srcGroupId, level + 1));
|
QRY_ERR_RET(qExplainAppendGroupResRows(ctx, pExchNode->srcGroupId, level + 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_SORT:{
|
case QUERY_NODE_PHYSICAL_PLAN_SORT:{
|
||||||
SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode;
|
SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode;
|
||||||
EXPLAIN_ROW_NEW(level, EXPLAIN_SORT_FORMAT, pSortNode->pSortKeys->length, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
|
EXPLAIN_ROW_NEW(level, EXPLAIN_SORT_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||||
if (pResNode->pExecInfo) {
|
if (pResNode->pExecInfo) {
|
||||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||||
}
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSortNode->pSortKeys->length);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->totalRowSize);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
if (pSortNode->node.pConditions) {
|
if (pSortNode->node.pConditions) {
|
||||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||||
QRY_ERR_RET(nodesNodeToSQL(pSortNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
QRY_ERR_RET(nodesNodeToSQL(pSortNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||||
|
@ -468,20 +642,34 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
||||||
}
|
}
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:{
|
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:{
|
||||||
SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
|
SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
|
||||||
EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, qGetNameFromColumnNode(pIntNode->pTspk), pIntNode->window.pFuncs->length,
|
EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->pTspk));
|
||||||
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, pIntNode->precision), pIntNode->intervalUnit,
|
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||||
pIntNode->offset, getPrecisionUnit(pIntNode->precision),
|
|
||||||
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, pIntNode->precision), pIntNode->slidingUnit,
|
|
||||||
pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
|
|
||||||
if (pResNode->pExecInfo) {
|
if (pResNode->pExecInfo) {
|
||||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||||
}
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize);
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT, INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, pIntNode->precision),
|
||||||
|
pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(pIntNode->precision),
|
||||||
|
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, pIntNode->precision), pIntNode->slidingUnit);
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
if (pIntNode->pFill) {
|
if (pIntNode->pFill) {
|
||||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_FORMAT, qFillModeString(pIntNode->pFill->mode));
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_FORMAT, getFillModeString(pIntNode->pFill->mode));
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
}
|
}
|
||||||
|
@ -496,18 +684,36 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:{
|
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:{
|
||||||
SSessionWinodwPhysiNode *pIntNode = (SSessionWinodwPhysiNode *)pNode;
|
SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
|
||||||
EXPLAIN_ROW_NEW(level, EXPLAIN_SESSION_FORMAT, pIntNode->gap, pIntNode->window.pFuncs->length, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
|
EXPLAIN_ROW_NEW(level, EXPLAIN_SESSION_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||||
if (pResNode->pExecInfo) {
|
if (pResNode->pExecInfo) {
|
||||||
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
|
||||||
}
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
}
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pSessNode->window.pFuncs->length);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->totalRowSize);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||||
|
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
if (pIntNode->window.node.pConditions) {
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pSessNode->window.node.pOutputDataBlockDesc->pSlots));
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||||
|
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->outputRowSize);
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_WINDOW_FORMAT, pSessNode->gap);
|
||||||
|
EXPLAIN_ROW_END();
|
||||||
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
|
if (pSessNode->window.node.pConditions) {
|
||||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
|
||||||
QRY_ERR_RET(nodesNodeToSQL(pIntNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
QRY_ERR_RET(nodesNodeToSQL(pSessNode->window.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
}
|
}
|
||||||
|
@ -540,7 +746,7 @@ int32_t qExplainResNodeToRows(SExplainResNode *pResNode, SExplainCtx *ctx, int32
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t qAppendTaskExplainResRows(void *pCtx, int32_t groupId, int32_t level) {
|
int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level) {
|
||||||
SExplainResNode *node = NULL;
|
SExplainResNode *node = NULL;
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
SExplainCtx *ctx = (SExplainCtx *)pCtx;
|
SExplainCtx *ctx = (SExplainCtx *)pCtx;
|
||||||
|
@ -551,19 +757,24 @@ int32_t qAppendTaskExplainResRows(void *pCtx, int32_t groupId, int32_t level) {
|
||||||
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRY_ERR_RET(qGenerateExplainResNode(group->plan->pNode, group->execInfo, &node));
|
QRY_ERR_RET(qExplainGenerateResNode(group->plan->pNode, group, &node));
|
||||||
|
|
||||||
|
if ((EXPLAIN_MODE_ANALYZE == ctx->mode) && (group->physiPlanNum != group->physiPlanExecNum)) {
|
||||||
|
qError("physiPlanNum %d mismatch with physiExecNum %d in group %d", group->physiPlanNum, group->physiPlanExecNum, groupId);
|
||||||
|
QRY_ERR_JRET(TSDB_CODE_QRY_APP_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
QRY_ERR_JRET(qExplainResNodeToRows(node, ctx, level));
|
QRY_ERR_JRET(qExplainResNodeToRows(node, ctx, level));
|
||||||
|
|
||||||
_return:
|
_return:
|
||||||
|
|
||||||
qFreeExplainResTree(node);
|
qExplainFreeResNode(node);
|
||||||
|
|
||||||
QRY_RET(code);
|
QRY_RET(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t qGetExplainRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
|
int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
|
||||||
SExplainCtx *pCtx = (SExplainCtx *)ctx;
|
SExplainCtx *pCtx = (SExplainCtx *)ctx;
|
||||||
int32_t rowNum = taosArrayGetSize(pCtx->rows);
|
int32_t rowNum = taosArrayGetSize(pCtx->rows);
|
||||||
if (rowNum <= 0) {
|
if (rowNum <= 0) {
|
||||||
|
@ -572,7 +783,7 @@ int32_t qGetExplainRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t colNum = 1;
|
int32_t colNum = 1;
|
||||||
int32_t rspSize = sizeof(SRetrieveTableRsp) + sizeof(int32_t) * colNum + sizeof(int32_t) * rowNum + pCtx->totalSize;
|
int32_t rspSize = sizeof(SRetrieveTableRsp) + sizeof(int32_t) * colNum + sizeof(int32_t) * rowNum + pCtx->dataSize;
|
||||||
SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)taosMemoryCalloc(1, rspSize);
|
SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)taosMemoryCalloc(1, rspSize);
|
||||||
if (NULL == rsp) {
|
if (NULL == rsp) {
|
||||||
qError("malloc SRetrieveTableRsp failed, size:%d", rspSize);
|
qError("malloc SRetrieveTableRsp failed, size:%d", rspSize);
|
||||||
|
@ -582,7 +793,7 @@ int32_t qGetExplainRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
|
||||||
rsp->completed = 1;
|
rsp->completed = 1;
|
||||||
rsp->numOfRows = htonl(rowNum);
|
rsp->numOfRows = htonl(rowNum);
|
||||||
|
|
||||||
*(int32_t *)rsp->data = htonl(pCtx->totalSize);
|
*(int32_t *)rsp->data = htonl(pCtx->dataSize);
|
||||||
|
|
||||||
int32_t *offset = (int32_t *)((char *)rsp->data + sizeof(int32_t));
|
int32_t *offset = (int32_t *)((char *)rsp->data + sizeof(int32_t));
|
||||||
char *data = (char *)(offset + rowNum);
|
char *data = (char *)(offset + rowNum);
|
||||||
|
@ -604,13 +815,13 @@ int32_t qGetExplainRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
|
|
||||||
|
int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
SNodeListNode *plans = NULL;
|
SNodeListNode *plans = NULL;
|
||||||
int32_t taskNum = 0;
|
int32_t taskNum = 0;
|
||||||
SExplainGroup *pGroup = NULL;
|
SExplainGroup *pGroup = NULL;
|
||||||
void *pCtx = NULL;
|
SExplainCtx *ctx = NULL;
|
||||||
int32_t rootGroupId = 0;
|
|
||||||
|
|
||||||
if (pDag->numOfSubplans <= 0) {
|
if (pDag->numOfSubplans <= 0) {
|
||||||
qError("invalid subplan num:%d", pDag->numOfSubplans);
|
qError("invalid subplan num:%d", pDag->numOfSubplans);
|
||||||
|
@ -629,7 +840,7 @@ int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
|
||||||
QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRY_ERR_JRET(qInitExplainCtx(&pCtx, groupHash, pDag->explainInfo.verbose));
|
QRY_ERR_JRET(qExplainInitCtx(&ctx, groupHash, pDag->explainInfo.verbose, pDag->explainInfo.ratio, pDag->explainInfo.mode));
|
||||||
|
|
||||||
for (int32_t i = 0; i < levelNum; ++i) {
|
for (int32_t i = 0; i < levelNum; ++i) {
|
||||||
plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
|
plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
|
||||||
|
@ -653,7 +864,10 @@ int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
SExplainGroup group = {.nodeNum = 1, .plan = plan, .execInfo = NULL};
|
SExplainGroup group = {0};
|
||||||
|
group.nodeNum = 1;
|
||||||
|
group.plan = plan;
|
||||||
|
|
||||||
if (0 != taosHashPut(groupHash, &plan->id.groupId, sizeof(plan->id.groupId), &group, sizeof(group))) {
|
if (0 != taosHashPut(groupHash, &plan->id.groupId, sizeof(plan->id.groupId), &group, sizeof(group))) {
|
||||||
qError("taosHashPut to explainGroupHash failed, taskIdx:%d", n);
|
qError("taosHashPut to explainGroupHash failed, taskIdx:%d", n);
|
||||||
QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||||
|
@ -666,22 +880,130 @@ int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
|
||||||
QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
|
QRY_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
rootGroupId = plan->id.groupId;
|
ctx->rootGroupId = plan->id.groupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("level %d group handled, taskNum:%d", i, taskNum);
|
qDebug("level %d group handled, taskNum:%d", i, taskNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRY_ERR_JRET(qAppendTaskExplainResRows(pCtx, rootGroupId, 0));
|
*pCtx = ctx;
|
||||||
|
|
||||||
QRY_ERR_JRET(qGetExplainRspFromCtx(pCtx, pRsp));
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
_return:
|
_return:
|
||||||
|
|
||||||
qFreeExplainCtx(pCtx);
|
qExplainFreeCtx(ctx);
|
||||||
|
|
||||||
QRY_RET(code);
|
QRY_RET(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t qExplainGenerateRsp(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
|
||||||
|
QRY_ERR_RET(qExplainAppendGroupResRows(pCtx, pCtx->rootGroupId, 0));
|
||||||
|
|
||||||
|
QRY_ERR_RET(qExplainGetRspFromCtx(pCtx, pRsp));
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp) {
|
||||||
|
SExplainResNode *node = NULL;
|
||||||
|
int32_t code = 0;
|
||||||
|
bool groupDone = false;
|
||||||
|
SExplainCtx *ctx = (SExplainCtx *)pCtx;
|
||||||
|
|
||||||
|
SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId));
|
||||||
|
if (NULL == group) {
|
||||||
|
qError("group %d not in groupHash", groupId);
|
||||||
|
taosMemoryFreeClear(pRspMsg->subplanInfo);
|
||||||
|
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosWLockLatch(&group->lock);
|
||||||
|
if (NULL == group->nodeExecInfo) {
|
||||||
|
group->nodeExecInfo = taosArrayInit(group->nodeNum, sizeof(SExplainRsp));
|
||||||
|
if (NULL == group->nodeExecInfo) {
|
||||||
|
qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
|
||||||
|
taosMemoryFreeClear(pRspMsg->subplanInfo);
|
||||||
|
taosWUnLockLatch(&group->lock);
|
||||||
|
|
||||||
|
QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
group->physiPlanExecNum = pRspMsg->numOfPlans;
|
||||||
|
} else if (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum) {
|
||||||
|
qError("group execInfo already full, size:%d, nodeNum:%d", (int32_t)taosArrayGetSize(group->nodeExecInfo), group->nodeNum);
|
||||||
|
taosMemoryFreeClear(pRspMsg->subplanInfo);
|
||||||
|
taosWUnLockLatch(&group->lock);
|
||||||
|
|
||||||
|
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (group->physiPlanExecNum != pRspMsg->numOfPlans) {
|
||||||
|
qError("physiPlanExecNum %d mismatch with others %d in group %d", pRspMsg->numOfPlans, group->physiPlanExecNum, groupId);
|
||||||
|
taosMemoryFreeClear(pRspMsg->subplanInfo);
|
||||||
|
taosWUnLockLatch(&group->lock);
|
||||||
|
|
||||||
|
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArrayPush(group->nodeExecInfo, pRspMsg);
|
||||||
|
groupDone = (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum);
|
||||||
|
|
||||||
|
taosWUnLockLatch(&group->lock);
|
||||||
|
|
||||||
|
if (groupDone && (taosHashGetSize(pCtx->groupHash) == atomic_add_fetch_32(&pCtx->groupDoneNum, 1))) {
|
||||||
|
if (atomic_load_8((int8_t *)&pCtx->execDone)) {
|
||||||
|
if (0 == taosWTryLockLatch(&pCtx->lock)) {
|
||||||
|
QRY_ERR_RET(qExplainGenerateRsp(pCtx, pRsp));
|
||||||
|
// LEAVE LOCK THERE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
|
||||||
|
int32_t code = 0;
|
||||||
|
SExplainCtx *pCtx = NULL;
|
||||||
|
|
||||||
|
QRY_ERR_RET(qExplainPrepareCtx(pDag, &pCtx));
|
||||||
|
|
||||||
|
QRY_ERR_JRET(qExplainGenerateRsp(pCtx, pRsp));
|
||||||
|
|
||||||
|
_return:
|
||||||
|
|
||||||
|
qExplainFreeCtx(pCtx);
|
||||||
|
|
||||||
|
QRY_RET(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int32_t startTs) {
|
||||||
|
QRY_ERR_RET(qExplainPrepareCtx(pDag, pCtx));
|
||||||
|
|
||||||
|
(*pCtx)->reqStartTs = startTs;
|
||||||
|
(*pCtx)->jobStartTs = taosGetTimestampMs();
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
|
||||||
|
int32_t code = 0;
|
||||||
|
pCtx->jobDoneTs = taosGetTimestampMs();
|
||||||
|
|
||||||
|
atomic_store_8((int8_t *)&pCtx->execDone, true);
|
||||||
|
|
||||||
|
if (taosHashGetSize(pCtx->groupHash) == atomic_load_32(&pCtx->groupDoneNum)) {
|
||||||
|
if (0 == taosWTryLockLatch(&pCtx->lock)) {
|
||||||
|
QRY_ERR_RET(qExplainGenerateRsp(pCtx, pRsp));
|
||||||
|
// LEAVE LOCK THERE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
aux_source_directory(src EXECUTOR_SRC)
|
aux_source_directory(src EXECUTOR_SRC)
|
||||||
#add_library(executor ${EXECUTOR_SRC})
|
#add_library(executor ${EXECUTOR_SRC})
|
||||||
|
|
||||||
|
|
||||||
#target_link_libraries(
|
|
||||||
# executor
|
|
||||||
# PRIVATE os util common function parser planner qcom tsdb
|
|
||||||
#)
|
|
||||||
|
|
||||||
add_library(executor STATIC ${EXECUTOR_SRC})
|
add_library(executor STATIC ${EXECUTOR_SRC})
|
||||||
#set_target_properties(executor PROPERTIES
|
#set_target_properties(executor PROPERTIES
|
||||||
# IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/libexecutor.a"
|
# IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/libexecutor.a"
|
||||||
# INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/include/libs/executor"
|
# INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/include/libs/executor"
|
||||||
# )
|
# )
|
||||||
|
|
||||||
target_link_libraries(executor
|
target_link_libraries(executor
|
||||||
PRIVATE os util common function parser planner qcom vnode scalar nodes
|
PRIVATE os util common function parser planner qcom vnode scalar nodes
|
||||||
)
|
)
|
||||||
|
|
|
@ -36,6 +36,7 @@ extern "C" {
|
||||||
#include "thash.h"
|
#include "thash.h"
|
||||||
#include "tlockfree.h"
|
#include "tlockfree.h"
|
||||||
#include "tpagedbuf.h"
|
#include "tpagedbuf.h"
|
||||||
|
#include "tmsg.h"
|
||||||
|
|
||||||
struct SColumnFilterElem;
|
struct SColumnFilterElem;
|
||||||
|
|
||||||
|
@ -165,7 +166,7 @@ typedef struct STaskCostInfo {
|
||||||
|
|
||||||
typedef struct SOperatorCostInfo {
|
typedef struct SOperatorCostInfo {
|
||||||
uint64_t openCost;
|
uint64_t openCost;
|
||||||
uint64_t execCost;
|
uint64_t totalCost;
|
||||||
} SOperatorCostInfo;
|
} SOperatorCostInfo;
|
||||||
|
|
||||||
typedef struct SOrder {
|
typedef struct SOrder {
|
||||||
|
@ -238,6 +239,7 @@ typedef bool (*__optr_decode_fn_t)(struct SOperatorInfo* pOperator, char *result
|
||||||
typedef int32_t (*__optr_open_fn_t)(struct SOperatorInfo* pOptr);
|
typedef int32_t (*__optr_open_fn_t)(struct SOperatorInfo* pOptr);
|
||||||
typedef SSDataBlock* (*__optr_fn_t)(struct SOperatorInfo* pOptr, bool* newgroup);
|
typedef SSDataBlock* (*__optr_fn_t)(struct SOperatorInfo* pOptr, bool* newgroup);
|
||||||
typedef void (*__optr_close_fn_t)(void* param, int32_t num);
|
typedef void (*__optr_close_fn_t)(void* param, int32_t num);
|
||||||
|
typedef int32_t (*__optr_get_explain_fn_t)(struct SOperatorInfo* pOptr, void **pOptrExplain);
|
||||||
|
|
||||||
typedef struct STaskIdInfo {
|
typedef struct STaskIdInfo {
|
||||||
uint64_t queryId; // this is also a request id
|
uint64_t queryId; // this is also a request id
|
||||||
|
@ -306,26 +308,27 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct SOperatorInfo {
|
typedef struct SOperatorInfo {
|
||||||
uint8_t operatorType;
|
uint8_t operatorType;
|
||||||
bool blockingOptr; // block operator or not
|
bool blockingOptr; // block operator or not
|
||||||
uint8_t status; // denote if current operator is completed
|
uint8_t status; // denote if current operator is completed
|
||||||
int32_t numOfOutput; // number of columns of the current operator results
|
int32_t numOfOutput; // number of columns of the current operator results
|
||||||
char* name; // name, used to show the query execution plan
|
char* name; // name, used to show the query execution plan
|
||||||
void* info; // extension attribution
|
void* info; // extension attribution
|
||||||
SExprInfo* pExpr;
|
SExprInfo* pExpr;
|
||||||
STaskRuntimeEnv* pRuntimeEnv; // todo remove it
|
STaskRuntimeEnv* pRuntimeEnv; // todo remove it
|
||||||
SExecTaskInfo* pTaskInfo;
|
SExecTaskInfo* pTaskInfo;
|
||||||
SOperatorCostInfo cost;
|
SOperatorCostInfo cost;
|
||||||
SResultInfo resultInfo;
|
SResultInfo resultInfo;
|
||||||
struct SOperatorInfo** pDownstream; // downstram pointer list
|
struct SOperatorInfo** pDownstream; // downstram pointer list
|
||||||
int32_t numOfDownstream; // number of downstream. The value is always ONE expect for join operator
|
int32_t numOfDownstream; // number of downstream. The value is always ONE expect for join operator
|
||||||
__optr_open_fn_t _openFn; // DO NOT invoke this function directly
|
__optr_open_fn_t _openFn; // DO NOT invoke this function directly
|
||||||
__optr_fn_t getNextFn;
|
__optr_fn_t getNextFn;
|
||||||
__optr_fn_t getStreamResFn; // execute the aggregate in the stream model.
|
__optr_fn_t getStreamResFn; // execute the aggregate in the stream model.
|
||||||
__optr_fn_t cleanupFn; // call this function to release the allocated resources ASAP
|
__optr_fn_t cleanupFn; // call this function to release the allocated resources ASAP
|
||||||
__optr_close_fn_t closeFn;
|
__optr_close_fn_t closeFn;
|
||||||
__optr_encode_fn_t encodeResultRow;
|
__optr_encode_fn_t encodeResultRow;
|
||||||
__optr_decode_fn_t decodeResultRow;
|
__optr_decode_fn_t decodeResultRow;
|
||||||
|
__optr_get_explain_fn_t getExplainFn;
|
||||||
} SOperatorInfo;
|
} SOperatorInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -385,6 +388,12 @@ typedef struct SExchangeInfo {
|
||||||
SLoadRemoteDataInfo loadInfo;
|
SLoadRemoteDataInfo loadInfo;
|
||||||
} SExchangeInfo;
|
} SExchangeInfo;
|
||||||
|
|
||||||
|
typedef struct SColMatchInfo {
|
||||||
|
int32_t colId;
|
||||||
|
int32_t targetSlotId;
|
||||||
|
bool output;
|
||||||
|
} SColMatchInfo;
|
||||||
|
|
||||||
typedef struct STableScanInfo {
|
typedef struct STableScanInfo {
|
||||||
void* dataReader;
|
void* dataReader;
|
||||||
int32_t numOfBlocks; // extract basic running information.
|
int32_t numOfBlocks; // extract basic running information.
|
||||||
|
@ -497,8 +506,9 @@ typedef struct SAggOperatorInfo {
|
||||||
|
|
||||||
typedef struct SProjectOperatorInfo {
|
typedef struct SProjectOperatorInfo {
|
||||||
SOptrBasicInfo binfo;
|
SOptrBasicInfo binfo;
|
||||||
|
SAggSupporter aggSup;
|
||||||
SSDataBlock *existDataBlock;
|
SSDataBlock *existDataBlock;
|
||||||
int32_t threshold;
|
SArray *pPseudoColInfo;
|
||||||
SLimit limit;
|
SLimit limit;
|
||||||
int64_t curOffset;
|
int64_t curOffset;
|
||||||
int64_t curOutput;
|
int64_t curOutput;
|
||||||
|
@ -544,6 +554,7 @@ typedef struct SGroupbyOperatorInfo {
|
||||||
SOptrBasicInfo binfo;
|
SOptrBasicInfo binfo;
|
||||||
SArray* pGroupCols;
|
SArray* pGroupCols;
|
||||||
SArray* pGroupColVals; // current group column values, SArray<SGroupKeys>
|
SArray* pGroupColVals; // current group column values, SArray<SGroupKeys>
|
||||||
|
SNode* pCondition;
|
||||||
bool isInit; // denote if current val is initialized or not
|
bool isInit; // denote if current val is initialized or not
|
||||||
char* keyBuf; // group by keys for hash
|
char* keyBuf; // group by keys for hash
|
||||||
int32_t groupKeyLen; // total group by column width
|
int32_t groupKeyLen; // total group by column width
|
||||||
|
@ -623,13 +634,31 @@ typedef struct SDistinctOperatorInfo {
|
||||||
SHashObj* pSet;
|
SHashObj* pSet;
|
||||||
SSDataBlock* pRes;
|
SSDataBlock* pRes;
|
||||||
bool recordNullVal; // has already record the null value, no need to try again
|
bool recordNullVal; // has already record the null value, no need to try again
|
||||||
int64_t threshold;
|
// int64_t threshold; // todo remove it
|
||||||
int64_t outputCapacity;
|
// int64_t outputCapacity;// todo remove it
|
||||||
int32_t totalBytes;
|
// int32_t totalBytes; // todo remove it
|
||||||
|
SResultInfo resInfo;
|
||||||
char* buf;
|
char* buf;
|
||||||
SArray* pDistinctDataInfo;
|
SArray* pDistinctDataInfo;
|
||||||
} SDistinctOperatorInfo;
|
} SDistinctOperatorInfo;
|
||||||
|
|
||||||
|
int32_t operatorDummyOpenFn(SOperatorInfo* pOperator);
|
||||||
|
void operatorDummyCloseFn(void* param, int32_t numOfCols);
|
||||||
|
int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num);
|
||||||
|
int32_t initAggInfo(SOptrBasicInfo* pBasicInfo, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||||
|
int32_t numOfRows, SSDataBlock* pResultBlock, const char* pkey);
|
||||||
|
void toSDatablock(SGroupResInfo* pGroupResInfo, SDiskbasedBuf* pBuf, SSDataBlock* pBlock, int32_t rowCapacity, int32_t* rowCellOffset);
|
||||||
|
void finalizeMultiTupleQueryResult(SqlFunctionCtx* pCtx, int32_t numOfOutput, SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset);
|
||||||
|
void doApplyFunctions(SqlFunctionCtx* pCtx, STimeWindow* pWin, SColumnInfoData* pTimeWindowData, int32_t offset, int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput, int32_t order);
|
||||||
|
int32_t setGroupResultOutputBuf_rv(SOptrBasicInfo* binfo, int32_t numOfCols, char* pData, int16_t type,
|
||||||
|
int16_t bytes, int32_t groupId, SDiskbasedBuf* pBuf, SExecTaskInfo* pTaskInfo, SAggSupporter* pAggSup);
|
||||||
|
void doDestroyBasicInfo(SOptrBasicInfo* pInfo, int32_t numOfOutput);
|
||||||
|
int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadInfo, int32_t numOfRows,
|
||||||
|
char* pData, int32_t compLen, int32_t numOfOutput, int64_t startTs,
|
||||||
|
uint64_t* total, SArray* pColList);
|
||||||
|
void doSetOperatorCompleted(SOperatorInfo* pOperator);
|
||||||
|
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock);
|
||||||
|
|
||||||
SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo);
|
SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo);
|
||||||
SOperatorInfo* createTableScanOperatorInfo(void* pTsdbReadHandle, int32_t order, int32_t numOfCols, int32_t repeatTime,
|
SOperatorInfo* createTableScanOperatorInfo(void* pTsdbReadHandle, int32_t order, int32_t numOfCols, int32_t repeatTime,
|
||||||
int32_t reverseTime, SArray* pColMatchInfo, SNode* pCondition, SExecTaskInfo* pTaskInfo);
|
int32_t reverseTime, SArray* pColMatchInfo, SNode* pCondition, SExecTaskInfo* pTaskInfo);
|
||||||
|
@ -645,14 +674,14 @@ SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
||||||
const STableGroupInfo* pTableGroupInfo, SExecTaskInfo* pTaskInfo);
|
const STableGroupInfo* pTableGroupInfo, SExecTaskInfo* pTaskInfo);
|
||||||
SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResBlock, int64_t gap, SExecTaskInfo* pTaskInfo);
|
SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResBlock, int64_t gap, SExecTaskInfo* pTaskInfo);
|
||||||
SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock,
|
SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock,
|
||||||
SArray* pGroupColList, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo);
|
SArray* pGroupColList, SNode* pCondition, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo);
|
||||||
SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SExecTaskInfo* pTaskInfo);
|
SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SExecTaskInfo* pTaskInfo);
|
||||||
|
SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock* pResBlock, SArray* pColList, SArray* pTableIdList, SExecTaskInfo* pTaskInfo);
|
||||||
|
|
||||||
SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SInterval* pInterval, SSDataBlock* pResBlock,
|
SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SInterval* pInterval, SSDataBlock* pResBlock,
|
||||||
int32_t fillType, char* fillVal, bool multigroupResult, SExecTaskInfo* pTaskInfo);
|
int32_t fillType, char* fillVal, bool multigroupResult, SExecTaskInfo* pTaskInfo);
|
||||||
SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo);
|
SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo);
|
||||||
SOperatorInfo* createDistinctOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr,
|
SOperatorInfo* createDistinctOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo);
|
||||||
int32_t numOfOutput);
|
|
||||||
|
|
||||||
SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv);
|
SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv);
|
||||||
SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream,
|
SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream,
|
||||||
|
@ -700,6 +729,7 @@ int32_t getMaximumIdleDurationSec();
|
||||||
void doInvokeUdf(struct SUdfInfo* pUdfInfo, SqlFunctionCtx* pCtx, int32_t idx, int32_t type);
|
void doInvokeUdf(struct SUdfInfo* pUdfInfo, SqlFunctionCtx* pCtx, int32_t idx, int32_t type);
|
||||||
void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status);
|
void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status);
|
||||||
int32_t createExecTaskInfoImpl(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SReadHandle* pHandle, uint64_t taskId, EOPTR_EXEC_MODEL model);
|
int32_t createExecTaskInfoImpl(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SReadHandle* pHandle, uint64_t taskId, EOPTR_EXEC_MODEL model);
|
||||||
|
int32_t getOperatorExplainExecInfo(SOperatorInfo *operatorInfo, SExplainExecInfo **pRes, int32_t *capacity, int32_t *resNum);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,3 +229,12 @@ void qDestroyTask(qTaskInfo_t qTaskHandle) {
|
||||||
queryCostStatis(pTaskInfo); // print the query cost summary
|
queryCostStatis(pTaskInfo); // print the query cost summary
|
||||||
doDestroyTask(pTaskInfo);
|
doDestroyTask(pTaskInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t qGetExplainExecInfo(qTaskInfo_t tinfo, int32_t *resNum, SExplainExecInfo **pRes) {
|
||||||
|
SExecTaskInfo *pTaskInfo = (SExecTaskInfo *)tinfo;
|
||||||
|
int32_t capacity = 0;
|
||||||
|
|
||||||
|
return getOperatorExplainExecInfo(pTaskInfo->pRoot, pRes, &capacity, resNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,507 @@
|
||||||
|
/*
|
||||||
|
* 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 "os.h"
|
||||||
|
#include "function.h"
|
||||||
|
#include "tname.h"
|
||||||
|
|
||||||
|
#include "tdatablock.h"
|
||||||
|
#include "tmsg.h"
|
||||||
|
|
||||||
|
#include "executorimpl.h"
|
||||||
|
#include "tcompare.h"
|
||||||
|
#include "thash.h"
|
||||||
|
#include "ttypes.h"
|
||||||
|
|
||||||
|
static void destroyGroupbyOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
|
SGroupbyOperatorInfo* pInfo = (SGroupbyOperatorInfo*)param;
|
||||||
|
doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
|
||||||
|
taosMemoryFreeClear(pInfo->keyBuf);
|
||||||
|
taosArrayDestroy(pInfo->pGroupCols);
|
||||||
|
taosArrayDestroy(pInfo->pGroupColVals);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t initGroupOptrInfo(SGroupbyOperatorInfo* pInfo, SArray* pGroupColList) {
|
||||||
|
pInfo->pGroupColVals = taosArrayInit(4, sizeof(SGroupKeys));
|
||||||
|
if (pInfo->pGroupColVals == NULL) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t numOfGroupCols = taosArrayGetSize(pGroupColList);
|
||||||
|
for (int32_t i = 0; i < numOfGroupCols; ++i) {
|
||||||
|
SColumn* pCol = taosArrayGet(pGroupColList, i);
|
||||||
|
pInfo->groupKeyLen += pCol->bytes;
|
||||||
|
|
||||||
|
struct SGroupKeys key = {0};
|
||||||
|
key.bytes = pCol->bytes;
|
||||||
|
key.type = pCol->type;
|
||||||
|
key.isNull = false;
|
||||||
|
key.pData = taosMemoryCalloc(1, pCol->bytes);
|
||||||
|
if (key.pData == NULL) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosArrayPush(pInfo->pGroupColVals, &key);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t nullFlagSize = sizeof(int8_t) * numOfGroupCols;
|
||||||
|
pInfo->keyBuf = taosMemoryCalloc(1, pInfo->groupKeyLen + nullFlagSize);
|
||||||
|
|
||||||
|
if (pInfo->keyBuf == NULL) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool groupKeyCompare(SGroupbyOperatorInfo* pInfo, SSDataBlock* pBlock, int32_t rowIndex,
|
||||||
|
int32_t numOfGroupCols) {
|
||||||
|
SColumnDataAgg* pColAgg = NULL;
|
||||||
|
for (int32_t i = 0; i < numOfGroupCols; ++i) {
|
||||||
|
SColumn* pCol = taosArrayGet(pInfo->pGroupCols, i);
|
||||||
|
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pCol->slotId);
|
||||||
|
if (pBlock->pBlockAgg != NULL) {
|
||||||
|
pColAgg = &pBlock->pBlockAgg[pCol->slotId]; // TODO is agg data matched?
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNull = colDataIsNull(pColInfoData, pBlock->info.rows, rowIndex, pColAgg);
|
||||||
|
|
||||||
|
SGroupKeys* pkey = taosArrayGet(pInfo->pGroupColVals, i);
|
||||||
|
if (pkey->isNull && isNull) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNull || pkey->isNull) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* val = colDataGetData(pColInfoData, rowIndex);
|
||||||
|
|
||||||
|
if (IS_VAR_DATA_TYPE(pkey->type)) {
|
||||||
|
int32_t len = varDataLen(val);
|
||||||
|
if (len == varDataLen(pkey->pData) && memcmp(varDataVal(pkey->pData), varDataVal(val), len) == 0) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (memcmp(pkey->pData, val, pkey->bytes) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void keepGroupKeys(SGroupbyOperatorInfo* pInfo, SSDataBlock* pBlock, int32_t rowIndex, int32_t numOfGroupCols) {
|
||||||
|
SColumnDataAgg* pColAgg = NULL;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < numOfGroupCols; ++i) {
|
||||||
|
SColumn* pCol = taosArrayGet(pInfo->pGroupCols, i);
|
||||||
|
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pCol->slotId);
|
||||||
|
|
||||||
|
if (pBlock->pBlockAgg != NULL) {
|
||||||
|
pColAgg = &pBlock->pBlockAgg[pCol->slotId]; // TODO is agg data matched?
|
||||||
|
}
|
||||||
|
|
||||||
|
SGroupKeys* pkey = taosArrayGet(pInfo->pGroupColVals, i);
|
||||||
|
if (colDataIsNull(pColInfoData, pBlock->info.rows, rowIndex, pColAgg)) {
|
||||||
|
pkey->isNull = true;
|
||||||
|
} else {
|
||||||
|
char* val = colDataGetData(pColInfoData, rowIndex);
|
||||||
|
if (IS_VAR_DATA_TYPE(pkey->type)) {
|
||||||
|
memcpy(pkey->pData, val, varDataTLen(val));
|
||||||
|
} else {
|
||||||
|
memcpy(pkey->pData, val, pkey->bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t generatedHashKey(void* pKey, int32_t* length, SArray* pGroupColVals) {
|
||||||
|
ASSERT(pKey != NULL);
|
||||||
|
size_t numOfGroupCols = taosArrayGetSize(pGroupColVals);
|
||||||
|
|
||||||
|
char* isNull = (char*)pKey;
|
||||||
|
char* pStart = (char*)pKey + sizeof(int8_t) * numOfGroupCols;
|
||||||
|
for (int32_t i = 0; i < numOfGroupCols; ++i) {
|
||||||
|
SGroupKeys* pkey = taosArrayGet(pGroupColVals, i);
|
||||||
|
if (pkey->isNull) {
|
||||||
|
isNull[i] = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
isNull[i] = 0;
|
||||||
|
if (IS_VAR_DATA_TYPE(pkey->type)) {
|
||||||
|
varDataCopy(pStart, pkey->pData);
|
||||||
|
pStart += varDataTLen(pkey->pData);
|
||||||
|
ASSERT(varDataTLen(pkey->pData) <= pkey->bytes);
|
||||||
|
} else {
|
||||||
|
memcpy(pStart, pkey->pData, pkey->bytes);
|
||||||
|
pStart += pkey->bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*length = (pStart - (char*)pKey);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign the group keys or user input constant values if required
|
||||||
|
static void doAssignGroupKeys(SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t totalRows, int32_t rowIndex) {
|
||||||
|
for (int32_t i = 0; i < numOfOutput; ++i) {
|
||||||
|
if (pCtx[i].functionId == -1) {
|
||||||
|
SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(&pCtx[i]);
|
||||||
|
|
||||||
|
SColumnInfoData* pColInfoData = pCtx[i].input.pData[0];
|
||||||
|
if (!colDataIsNull(pColInfoData, totalRows, rowIndex, NULL)) {
|
||||||
|
char* dest = GET_ROWCELL_INTERBUF(pEntryInfo);
|
||||||
|
char* data = colDataGetData(pColInfoData, rowIndex);
|
||||||
|
|
||||||
|
// set result exists, todo refactor
|
||||||
|
memcpy(dest, data, pColInfoData->info.bytes);
|
||||||
|
pEntryInfo->hasResult = DATA_SET_FLAG;
|
||||||
|
pEntryInfo->numOfRes = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
|
||||||
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
|
SGroupbyOperatorInfo* pInfo = pOperator->info;
|
||||||
|
|
||||||
|
SqlFunctionCtx* pCtx = pInfo->binfo.pCtx;
|
||||||
|
int32_t numOfGroupCols = taosArrayGetSize(pInfo->pGroupCols);
|
||||||
|
// if (type == TSDB_DATA_TYPE_FLOAT || type == TSDB_DATA_TYPE_DOUBLE) {
|
||||||
|
// qError("QInfo:0x%"PRIx64" group by not supported on double/float columns, abort", GET_TASKID(pRuntimeEnv));
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
int32_t len = 0;
|
||||||
|
STimeWindow w = TSWINDOW_INITIALIZER;
|
||||||
|
|
||||||
|
int32_t num = 0;
|
||||||
|
for (int32_t j = 0; j < pBlock->info.rows; ++j) {
|
||||||
|
// Compare with the previous row of this column, and do not set the output buffer again if they are identical.
|
||||||
|
if (!pInfo->isInit) {
|
||||||
|
keepGroupKeys(pInfo, pBlock, j, numOfGroupCols);
|
||||||
|
pInfo->isInit = true;
|
||||||
|
num++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equal = groupKeyCompare(pInfo, pBlock, j, numOfGroupCols);
|
||||||
|
if (equal) {
|
||||||
|
num++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*int32_t ret = */ generatedHashKey(pInfo->keyBuf, &len, pInfo->pGroupColVals);
|
||||||
|
int32_t ret = setGroupResultOutputBuf_rv(&(pInfo->binfo), pOperator->numOfOutput, pInfo->keyBuf, TSDB_DATA_TYPE_VARCHAR, len, 0, pInfo->aggSup.pResultBuf, pTaskInfo, &pInfo->aggSup);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
||||||
|
longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t rowIndex = j - num;
|
||||||
|
doApplyFunctions(pCtx, &w, NULL, rowIndex, num, NULL, pBlock->info.rows, pOperator->numOfOutput, TSDB_ORDER_ASC);
|
||||||
|
|
||||||
|
// assign the group keys or user input constant values if required
|
||||||
|
doAssignGroupKeys(pCtx, pOperator->numOfOutput, pBlock->info.rows, rowIndex);
|
||||||
|
keepGroupKeys(pInfo, pBlock, j, numOfGroupCols);
|
||||||
|
num = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num > 0) {
|
||||||
|
/*int32_t ret = */ generatedHashKey(pInfo->keyBuf, &len, pInfo->pGroupColVals);
|
||||||
|
int32_t ret =
|
||||||
|
setGroupResultOutputBuf_rv(&(pInfo->binfo), pOperator->numOfOutput, pInfo->keyBuf, TSDB_DATA_TYPE_VARCHAR, len,
|
||||||
|
0, pInfo->aggSup.pResultBuf, pTaskInfo, &pInfo->aggSup);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
longjmp(pTaskInfo->env, TSDB_CODE_QRY_APP_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t rowIndex = pBlock->info.rows - num;
|
||||||
|
doApplyFunctions(pCtx, &w, NULL, rowIndex, num, NULL, pBlock->info.rows, pOperator->numOfOutput, TSDB_ORDER_ASC);
|
||||||
|
doAssignGroupKeys(pCtx, pOperator->numOfOutput, pBlock->info.rows, rowIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator, bool* newgroup) {
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SGroupbyOperatorInfo* pInfo = pOperator->info;
|
||||||
|
SSDataBlock* pRes = pInfo->binfo.pRes;
|
||||||
|
|
||||||
|
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||||
|
toSDatablock(&pInfo->groupResInfo, pInfo->aggSup.pResultBuf, pRes, pInfo->binfo.capacity, pInfo->binfo.rowCellInfoOffset);
|
||||||
|
if (pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) {
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
}
|
||||||
|
return pRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t order = TSDB_ORDER_ASC;
|
||||||
|
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||||
|
SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
|
||||||
|
publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||||
|
if (pBlock == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the pDataBlock are always the same one, no need to call this again
|
||||||
|
setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order);
|
||||||
|
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->binfo.pCtx, pOperator->numOfOutput);
|
||||||
|
doHashGroupbyAgg(pOperator, pBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
pOperator->status = OP_RES_TO_RETURN;
|
||||||
|
closeAllResultRows(&pInfo->binfo.resultRowInfo);
|
||||||
|
|
||||||
|
finalizeMultiTupleQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput, pInfo->aggSup.pResultBuf,
|
||||||
|
&pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset);
|
||||||
|
// if (!stableQuery) { // finalize include the update of result rows
|
||||||
|
// finalizeQueryResult(pInfo->binfo.pCtx, pOperator->numOfOutput);
|
||||||
|
// } else {
|
||||||
|
// updateNumOfRowsInResultRows(pInfo->binfo.pCtx, pOperator->numOfOutput, &pInfo->binfo.resultRowInfo,
|
||||||
|
// pInfo->binfo.rowCellInfoOffset);
|
||||||
|
// }
|
||||||
|
|
||||||
|
blockDataEnsureCapacity(pRes, pInfo->binfo.capacity);
|
||||||
|
initGroupResInfo(&pInfo->groupResInfo, &pInfo->binfo.resultRowInfo);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
toSDatablock(&pInfo->groupResInfo, pInfo->aggSup.pResultBuf, pRes, pInfo->binfo.capacity,
|
||||||
|
pInfo->binfo.rowCellInfoOffset);
|
||||||
|
doFilter(pInfo->pCondition, pRes);
|
||||||
|
|
||||||
|
bool hasRemain = hasRemainDataInCurrentGroup(&pInfo->groupResInfo);
|
||||||
|
if (!hasRemain) {
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRes->info.rows > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pInfo->binfo.pRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock, SArray* pGroupColList, SNode* pCondition, SExecTaskInfo* pTaskInfo,
|
||||||
|
const STableGroupInfo* pTableGroupInfo) {
|
||||||
|
SGroupbyOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SGroupbyOperatorInfo));
|
||||||
|
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||||
|
if (pInfo == NULL || pOperator == NULL) {
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->pGroupCols = pGroupColList;
|
||||||
|
pInfo->pCondition = pCondition;
|
||||||
|
initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, 4096, pResultBlock, pTaskInfo->id.str);
|
||||||
|
initResultRowInfo(&pInfo->binfo.resultRowInfo, 8);
|
||||||
|
|
||||||
|
int32_t code = initGroupOptrInfo(pInfo, pGroupColList);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
pOperator->name = "GroupbyAggOperator";
|
||||||
|
pOperator->blockingOptr = true;
|
||||||
|
pOperator->status = OP_NOT_OPENED;
|
||||||
|
// pOperator->operatorType = OP_Groupby;
|
||||||
|
pOperator->pExpr = pExprInfo;
|
||||||
|
pOperator->numOfOutput = numOfCols;
|
||||||
|
pOperator->info = pInfo;
|
||||||
|
pOperator->_openFn = operatorDummyOpenFn;
|
||||||
|
pOperator->getNextFn = hashGroupbyAggregate;
|
||||||
|
pOperator->closeFn = destroyGroupbyOperatorInfo;
|
||||||
|
|
||||||
|
code = appendDownstream(pOperator, &downstream, 1);
|
||||||
|
return pOperator;
|
||||||
|
|
||||||
|
_error:
|
||||||
|
taosMemoryFreeClear(pInfo);
|
||||||
|
taosMemoryFreeClear(pOperator);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MULTI_KEY_DELIM "-"
|
||||||
|
|
||||||
|
static void destroyDistinctOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
|
SDistinctOperatorInfo* pInfo = (SDistinctOperatorInfo*)param;
|
||||||
|
taosHashCleanup(pInfo->pSet);
|
||||||
|
taosMemoryFreeClear(pInfo->buf);
|
||||||
|
taosArrayDestroy(pInfo->pDistinctDataInfo);
|
||||||
|
pInfo->pRes = blockDataDestroy(pInfo->pRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void buildMultiDistinctKey(SDistinctOperatorInfo* pInfo, SSDataBlock* pBlock, int32_t rowId) {
|
||||||
|
char* p = pInfo->buf;
|
||||||
|
// memset(p, 0, pInfo->totalBytes);
|
||||||
|
|
||||||
|
for (int i = 0; i < taosArrayGetSize(pInfo->pDistinctDataInfo); i++) {
|
||||||
|
SDistinctDataInfo* pDistDataInfo = (SDistinctDataInfo*)taosArrayGet(pInfo->pDistinctDataInfo, i);
|
||||||
|
SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, pDistDataInfo->index);
|
||||||
|
|
||||||
|
char* val = ((char*)pColDataInfo->pData) + pColDataInfo->info.bytes * rowId;
|
||||||
|
if (isNull(val, pDistDataInfo->type)) {
|
||||||
|
p += pDistDataInfo->bytes;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (IS_VAR_DATA_TYPE(pDistDataInfo->type)) {
|
||||||
|
memcpy(p, varDataVal(val), varDataLen(val));
|
||||||
|
p += varDataLen(val);
|
||||||
|
} else {
|
||||||
|
memcpy(p, val, pDistDataInfo->bytes);
|
||||||
|
p += pDistDataInfo->bytes;
|
||||||
|
}
|
||||||
|
memcpy(p, MULTI_KEY_DELIM, strlen(MULTI_KEY_DELIM));
|
||||||
|
p += strlen(MULTI_KEY_DELIM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool initMultiDistinctInfo(SDistinctOperatorInfo* pInfo, SOperatorInfo* pOperator) {
|
||||||
|
for (int i = 0; i < pOperator->numOfOutput; i++) {
|
||||||
|
// pInfo->totalBytes += pOperator->pExpr[i].base.colBytes;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
for (int i = 0; i < pOperator->numOfOutput; i++) {
|
||||||
|
int numOfCols = (int)(taosArrayGetSize(pBlock->pDataBlock));
|
||||||
|
assert(i < numOfCols);
|
||||||
|
|
||||||
|
for (int j = 0; j < numOfCols; j++) {
|
||||||
|
SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, j);
|
||||||
|
if (pColDataInfo->info.colId == pOperator->pExpr[i].base.resSchema.colId) {
|
||||||
|
SDistinctDataInfo item = {.index = j, .type = pColDataInfo->info.type, .bytes = pColDataInfo->info.bytes};
|
||||||
|
taosArrayInsert(pInfo->pDistinctDataInfo, i, &item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// pInfo->totalBytes += (int32_t)strlen(MULTI_KEY_DELIM) * (pOperator->numOfOutput);
|
||||||
|
// pInfo->buf = taosMemoryCalloc(1, pInfo->totalBytes);
|
||||||
|
return taosArrayGetSize(pInfo->pDistinctDataInfo) == pOperator->numOfOutput ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SSDataBlock* hashDistinct(SOperatorInfo* pOperator, bool* newgroup) {
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDistinctOperatorInfo* pInfo = pOperator->info;
|
||||||
|
SSDataBlock* pRes = pInfo->pRes;
|
||||||
|
|
||||||
|
pRes->info.rows = 0;
|
||||||
|
SSDataBlock* pBlock = NULL;
|
||||||
|
|
||||||
|
SOperatorInfo* pDownstream = pOperator->pDownstream[0];
|
||||||
|
while (1) {
|
||||||
|
publishOperatorProfEvent(pDownstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||||
|
pBlock = pDownstream->getNextFn(pDownstream, newgroup);
|
||||||
|
publishOperatorProfEvent(pDownstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||||
|
|
||||||
|
if (pBlock == NULL) {
|
||||||
|
doSetOperatorCompleted(pOperator);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure result output buf
|
||||||
|
if (pRes->info.rows + pBlock->info.rows > pInfo->resInfo.capacity) {
|
||||||
|
int32_t newSize = pRes->info.rows + pBlock->info.rows;
|
||||||
|
for (int i = 0; i < taosArrayGetSize(pRes->pDataBlock); i++) {
|
||||||
|
SColumnInfoData* pResultColInfoData = taosArrayGet(pRes->pDataBlock, i);
|
||||||
|
SDistinctDataInfo* pDistDataInfo = taosArrayGet(pInfo->pDistinctDataInfo, i);
|
||||||
|
|
||||||
|
// char* tmp = taosMemoryRealloc(pResultColInfoData->pData, newSize * pDistDataInfo->bytes);
|
||||||
|
// if (tmp == NULL) {
|
||||||
|
// return NULL;
|
||||||
|
// } else {
|
||||||
|
// pResultColInfoData->pData = tmp;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
pInfo->resInfo.capacity = newSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pBlock->info.rows; i++) {
|
||||||
|
buildMultiDistinctKey(pInfo, pBlock, i);
|
||||||
|
if (taosHashGet(pInfo->pSet, pInfo->buf, 0) == NULL) {
|
||||||
|
taosHashPut(pInfo->pSet, pInfo->buf, 0, NULL, 0);
|
||||||
|
|
||||||
|
for (int j = 0; j < taosArrayGetSize(pRes->pDataBlock); j++) {
|
||||||
|
SDistinctDataInfo* pDistDataInfo = taosArrayGet(pInfo->pDistinctDataInfo, j); // distinct meta info
|
||||||
|
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pDistDataInfo->index); // src
|
||||||
|
SColumnInfoData* pResultColInfoData = taosArrayGet(pRes->pDataBlock, j); // dist
|
||||||
|
|
||||||
|
char* val = ((char*)pColInfoData->pData) + pDistDataInfo->bytes * i;
|
||||||
|
char* start = pResultColInfoData->pData + pDistDataInfo->bytes * pInfo->pRes->info.rows;
|
||||||
|
memcpy(start, val, pDistDataInfo->bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
pRes->info.rows += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRes->info.rows >= pInfo->resInfo.threshold) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (pInfo->pRes->info.rows > 0) ? pInfo->pRes : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOperatorInfo* createDistinctOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SSDataBlock* pResBlock, SExecTaskInfo* pTaskInfo) {
|
||||||
|
SDistinctOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SDistinctOperatorInfo));
|
||||||
|
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||||
|
if (pInfo == NULL || pOperator == NULL) {
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
pOperator->resultInfo.capacity = 4096; // todo extract function.
|
||||||
|
|
||||||
|
// pInfo->totalBytes = 0;
|
||||||
|
pInfo->buf = NULL;
|
||||||
|
|
||||||
|
pInfo->pDistinctDataInfo = taosArrayInit(numOfCols, sizeof(SDistinctDataInfo));
|
||||||
|
initMultiDistinctInfo(pInfo, pOperator);
|
||||||
|
|
||||||
|
pInfo->pSet = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||||
|
|
||||||
|
pOperator->name = "DistinctOperator";
|
||||||
|
pOperator->blockingOptr = true;
|
||||||
|
pOperator->status = OP_NOT_OPENED;
|
||||||
|
// pOperator->operatorType = DISTINCT;
|
||||||
|
pOperator->pExpr = pExpr;
|
||||||
|
pOperator->numOfOutput = numOfCols;
|
||||||
|
pOperator->info = pInfo;
|
||||||
|
pOperator->getNextFn = hashDistinct;
|
||||||
|
pOperator->closeFn = destroyDistinctOperatorInfo;
|
||||||
|
|
||||||
|
int32_t code = appendDownstream(pOperator, &downstream, 1);
|
||||||
|
return pOperator;
|
||||||
|
|
||||||
|
_error:
|
||||||
|
pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
taosMemoryFree(pInfo);
|
||||||
|
taosMemoryFree(pOperator);
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,834 @@
|
||||||
|
/*
|
||||||
|
* 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 "tglobal.h"
|
||||||
|
#include "filter.h"
|
||||||
|
#include "function.h"
|
||||||
|
#include "os.h"
|
||||||
|
#include "querynodes.h"
|
||||||
|
#include "tname.h"
|
||||||
|
#include "vnode.h"
|
||||||
|
|
||||||
|
#include "tdatablock.h"
|
||||||
|
#include "tmsg.h"
|
||||||
|
|
||||||
|
#include "executorimpl.h"
|
||||||
|
#include "query.h"
|
||||||
|
#include "tcompare.h"
|
||||||
|
#include "thash.h"
|
||||||
|
#include "tsdb.h"
|
||||||
|
#include "ttypes.h"
|
||||||
|
|
||||||
|
#define SET_REVERSE_SCAN_FLAG(_info) ((_info)->scanFlag = REVERSE_SCAN)
|
||||||
|
#define SWITCH_ORDER(n) (((n) = ((n) == TSDB_ORDER_ASC) ? TSDB_ORDER_DESC : TSDB_ORDER_ASC))
|
||||||
|
|
||||||
|
|
||||||
|
void switchCtxOrder(SqlFunctionCtx* pCtx, int32_t numOfOutput) {
|
||||||
|
for (int32_t i = 0; i < numOfOutput; ++i) {
|
||||||
|
SWITCH_ORDER(pCtx[i].order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setupQueryRangeForReverseScan(STableScanInfo* pTableScanInfo) {
|
||||||
|
#if 0
|
||||||
|
int32_t numOfGroups = (int32_t)(GET_NUM_OF_TABLEGROUP(pRuntimeEnv));
|
||||||
|
for(int32_t i = 0; i < numOfGroups; ++i) {
|
||||||
|
SArray *group = GET_TABLEGROUP(pRuntimeEnv, i);
|
||||||
|
SArray *tableKeyGroup = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i);
|
||||||
|
|
||||||
|
size_t t = taosArrayGetSize(group);
|
||||||
|
for (int32_t j = 0; j < t; ++j) {
|
||||||
|
STableQueryInfo *pCheckInfo = taosArrayGetP(group, j);
|
||||||
|
updateTableQueryInfoForReverseScan(pCheckInfo);
|
||||||
|
|
||||||
|
// update the last key in tableKeyInfo list, the tableKeyInfo is used to build the tsdbQueryHandle and decide
|
||||||
|
// the start check timestamp of tsdbQueryHandle
|
||||||
|
// STableKeyInfo *pTableKeyInfo = taosArrayGet(tableKeyGroup, j);
|
||||||
|
// pTableKeyInfo->lastKey = pCheckInfo->lastKey;
|
||||||
|
//
|
||||||
|
// assert(pCheckInfo->pTable == pTableKeyInfo->pTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t loadDataBlock(SExecTaskInfo* pTaskInfo, STableScanInfo* pTableScanInfo, SSDataBlock* pBlock, uint32_t* status) {
|
||||||
|
STaskCostInfo* pCost = &pTaskInfo->cost;
|
||||||
|
|
||||||
|
pCost->totalBlocks += 1;
|
||||||
|
pCost->totalRows += pBlock->info.rows;
|
||||||
|
|
||||||
|
pCost->totalCheckedRows += pBlock->info.rows;
|
||||||
|
pCost->loadBlocks += 1;
|
||||||
|
|
||||||
|
*status = BLK_DATA_ALL_NEEDED;
|
||||||
|
|
||||||
|
SArray* pCols = tsdbRetrieveDataBlock(pTableScanInfo->dataReader, NULL);
|
||||||
|
if (pCols == NULL) {
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t numOfCols = pBlock->info.numOfCols;
|
||||||
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
|
SColumnInfoData* p = taosArrayGet(pCols, i);
|
||||||
|
SColMatchInfo* pColMatchInfo = taosArrayGet(pTableScanInfo->pColMatchInfo, i);
|
||||||
|
if (!pColMatchInfo->output) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(pColMatchInfo->colId == p->info.colId);
|
||||||
|
taosArraySet(pBlock->pDataBlock, pColMatchInfo->targetSlotId, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
doFilter(pTableScanInfo->pFilterNode, pBlock);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setupEnvForReverseScan(STableScanInfo* pTableScanInfo, SqlFunctionCtx* pCtx, int32_t numOfOutput) {
|
||||||
|
// reverse order time range
|
||||||
|
SET_REVERSE_SCAN_FLAG(pTableScanInfo);
|
||||||
|
|
||||||
|
switchCtxOrder(pCtx, numOfOutput);
|
||||||
|
SWITCH_ORDER(pTableScanInfo->order);
|
||||||
|
setupQueryRangeForReverseScan(pTableScanInfo);
|
||||||
|
|
||||||
|
pTableScanInfo->times = 1;
|
||||||
|
pTableScanInfo->current = 0;
|
||||||
|
pTableScanInfo->reverseTimes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator, bool* newgroup) {
|
||||||
|
STableScanInfo* pTableScanInfo = pOperator->info;
|
||||||
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
|
|
||||||
|
SSDataBlock* pBlock = &pTableScanInfo->block;
|
||||||
|
STableGroupInfo* pTableGroupInfo = &pOperator->pTaskInfo->tableqinfoGroupInfo;
|
||||||
|
|
||||||
|
*newgroup = false;
|
||||||
|
|
||||||
|
while (tsdbNextDataBlock(pTableScanInfo->dataReader)) {
|
||||||
|
if (isTaskKilled(pOperator->pTaskInfo)) {
|
||||||
|
longjmp(pOperator->pTaskInfo->env, TSDB_CODE_TSC_QUERY_CANCELLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
pTableScanInfo->numOfBlocks += 1;
|
||||||
|
tsdbRetrieveDataBlockInfo(pTableScanInfo->dataReader, &pBlock->info);
|
||||||
|
|
||||||
|
// todo opt
|
||||||
|
// if (pTableGroupInfo->numOfTables > 1 || (pRuntimeEnv->current == NULL && pTableGroupInfo->numOfTables == 1)) {
|
||||||
|
// STableQueryInfo** pTableQueryInfo =
|
||||||
|
// (STableQueryInfo**)taosHashGet(pTableGroupInfo->map, &pBlock->info.uid, sizeof(pBlock->info.uid));
|
||||||
|
// if (pTableQueryInfo == NULL) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// doTableQueryInfoTimeWindowCheck(pTaskInfo, *pTableQueryInfo, pTableScanInfo->order);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// this function never returns error?
|
||||||
|
uint32_t status = BLK_DATA_ALL_NEEDED;
|
||||||
|
int32_t code = loadDataBlock(pTaskInfo, pTableScanInfo, pBlock, &status);
|
||||||
|
// int32_t code = loadDataBlockOnDemand(pOperator->pRuntimeEnv, pTableScanInfo, pBlock, &status);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
longjmp(pOperator->pTaskInfo->env, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
// current block is ignored according to filter result by block statistics data, continue load the next block
|
||||||
|
if (status == BLK_DATA_DISCARD || pBlock->info.rows == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SSDataBlock* doTableScan(SOperatorInfo* pOperator, bool* newgroup) {
|
||||||
|
STableScanInfo* pTableScanInfo = pOperator->info;
|
||||||
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
|
|
||||||
|
// The read handle is not initialized yet, since no qualified tables exists
|
||||||
|
if (pTableScanInfo->dataReader == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SResultRowInfo* pResultRowInfo = pTableScanInfo->pResultRowInfo;
|
||||||
|
*newgroup = false;
|
||||||
|
|
||||||
|
while (pTableScanInfo->current < pTableScanInfo->times) {
|
||||||
|
SSDataBlock* p = doTableScanImpl(pOperator, newgroup);
|
||||||
|
if (p != NULL) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++pTableScanInfo->current >= pTableScanInfo->times) {
|
||||||
|
if (pTableScanInfo->reverseTimes <= 0 /* || isTsdbCacheLastRow(pTableScanInfo->pTsdbReadHandle)*/) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do prepare for the next round table scan operation
|
||||||
|
// STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window);
|
||||||
|
// tsdbResetQueryHandle(pTableScanInfo->pTsdbReadHandle, &cond);
|
||||||
|
|
||||||
|
setTaskStatus(pTaskInfo, TASK_NOT_COMPLETED);
|
||||||
|
pTableScanInfo->scanFlag = REPEAT_SCAN;
|
||||||
|
|
||||||
|
if (pResultRowInfo->size > 0) {
|
||||||
|
pResultRowInfo->curPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug("%s start to repeat scan data blocks due to query func required, qrange:%" PRId64 "-%" PRId64,
|
||||||
|
GET_TASKID(pTaskInfo), pTaskInfo->window.skey, pTaskInfo->window.ekey);
|
||||||
|
}
|
||||||
|
|
||||||
|
SSDataBlock* p = NULL;
|
||||||
|
// todo refactor
|
||||||
|
if (pTableScanInfo->reverseTimes > 0) {
|
||||||
|
setupEnvForReverseScan(pTableScanInfo, pTableScanInfo->pCtx, pTableScanInfo->numOfOutput);
|
||||||
|
// STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window);
|
||||||
|
// tsdbResetQueryHandle(pTableScanInfo->pTsdbReadHandle, &cond);
|
||||||
|
|
||||||
|
qDebug("%s start to reverse scan data blocks due to query func required, qrange:%" PRId64 "-%" PRId64,
|
||||||
|
GET_TASKID(pTaskInfo), pTaskInfo->window.skey, pTaskInfo->window.ekey);
|
||||||
|
|
||||||
|
if (pResultRowInfo->size > 0) {
|
||||||
|
pResultRowInfo->curPos = pResultRowInfo->size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = doTableScanImpl(pOperator, newgroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOperatorInfo* createTableScanOperatorInfo(void* pTsdbReadHandle, int32_t order, int32_t numOfOutput,
|
||||||
|
int32_t repeatTime, int32_t reverseTime, SArray* pColMatchInfo,
|
||||||
|
SNode* pCondition, SExecTaskInfo* pTaskInfo) {
|
||||||
|
assert(repeatTime > 0);
|
||||||
|
|
||||||
|
STableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableScanInfo));
|
||||||
|
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||||
|
if (pInfo == NULL || pOperator == NULL) {
|
||||||
|
taosMemoryFreeClear(pInfo);
|
||||||
|
taosMemoryFreeClear(pOperator);
|
||||||
|
|
||||||
|
pTaskInfo->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->block.pDataBlock = taosArrayInit(numOfOutput, sizeof(SColumnInfoData));
|
||||||
|
for (int32_t i = 0; i < numOfOutput; ++i) {
|
||||||
|
SColumnInfoData idata = {0};
|
||||||
|
taosArrayPush(pInfo->block.pDataBlock, &idata);
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->pFilterNode = pCondition;
|
||||||
|
pInfo->dataReader = pTsdbReadHandle;
|
||||||
|
pInfo->times = repeatTime;
|
||||||
|
pInfo->reverseTimes = reverseTime;
|
||||||
|
pInfo->order = order;
|
||||||
|
pInfo->current = 0;
|
||||||
|
pInfo->scanFlag = MAIN_SCAN;
|
||||||
|
pInfo->pColMatchInfo = pColMatchInfo;
|
||||||
|
pOperator->name = "TableScanOperator";
|
||||||
|
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN;
|
||||||
|
pOperator->blockingOptr = false;
|
||||||
|
pOperator->status = OP_NOT_OPENED;
|
||||||
|
pOperator->info = pInfo;
|
||||||
|
pOperator->numOfOutput = numOfOutput;
|
||||||
|
pOperator->getNextFn = doTableScan;
|
||||||
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
|
||||||
|
return pOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv) {
|
||||||
|
STableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableScanInfo));
|
||||||
|
|
||||||
|
pInfo->dataReader = pTsdbReadHandle;
|
||||||
|
pInfo->times = 1;
|
||||||
|
pInfo->reverseTimes = 0;
|
||||||
|
pInfo->order = pRuntimeEnv->pQueryAttr->order.order;
|
||||||
|
pInfo->current = 0;
|
||||||
|
pInfo->prevGroupId = -1;
|
||||||
|
pRuntimeEnv->enableGroupData = true;
|
||||||
|
|
||||||
|
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||||
|
pOperator->name = "TableSeqScanOperator";
|
||||||
|
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN;
|
||||||
|
pOperator->blockingOptr = false;
|
||||||
|
pOperator->status = OP_NOT_OPENED;
|
||||||
|
pOperator->info = pInfo;
|
||||||
|
pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols;
|
||||||
|
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||||
|
pOperator->getNextFn = doTableScanImpl;
|
||||||
|
|
||||||
|
return pOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SSDataBlock* doBlockInfoScan(SOperatorInfo* pOperator, bool* newgroup) {
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
STableScanInfo* pTableScanInfo = pOperator->info;
|
||||||
|
*newgroup = false;
|
||||||
|
|
||||||
|
STableBlockDistInfo tableBlockDist = {0};
|
||||||
|
tableBlockDist.numOfTables = 1; // TODO set the correct number of tables
|
||||||
|
|
||||||
|
int32_t numRowSteps = TSDB_DEFAULT_MAX_ROW_FBLOCK / TSDB_BLOCK_DIST_STEP_ROWS;
|
||||||
|
if (TSDB_DEFAULT_MAX_ROW_FBLOCK % TSDB_BLOCK_DIST_STEP_ROWS != 0) {
|
||||||
|
++numRowSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
tableBlockDist.dataBlockInfos = taosArrayInit(numRowSteps, sizeof(SFileBlockInfo));
|
||||||
|
taosArraySetSize(tableBlockDist.dataBlockInfos, numRowSteps);
|
||||||
|
|
||||||
|
tableBlockDist.maxRows = INT_MIN;
|
||||||
|
tableBlockDist.minRows = INT_MAX;
|
||||||
|
|
||||||
|
tsdbGetFileBlocksDistInfo(pTableScanInfo->dataReader, &tableBlockDist);
|
||||||
|
tableBlockDist.numOfRowsInMemTable = (int32_t) tsdbGetNumOfRowsInMemTable(pTableScanInfo->dataReader);
|
||||||
|
|
||||||
|
SSDataBlock* pBlock = &pTableScanInfo->block;
|
||||||
|
pBlock->info.rows = 1;
|
||||||
|
pBlock->info.numOfCols = 1;
|
||||||
|
|
||||||
|
// SBufferWriter bw = tbufInitWriter(NULL, false);
|
||||||
|
// blockDistInfoToBinary(&tableBlockDist, &bw);
|
||||||
|
SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, 0);
|
||||||
|
|
||||||
|
// int32_t len = (int32_t) tbufTell(&bw);
|
||||||
|
// pColInfo->pData = taosMemoryMalloc(len + sizeof(int32_t));
|
||||||
|
// *(int32_t*) pColInfo->pData = len;
|
||||||
|
// memcpy(pColInfo->pData + sizeof(int32_t), tbufGetData(&bw, false), len);
|
||||||
|
//
|
||||||
|
// tbufCloseWriter(&bw);
|
||||||
|
|
||||||
|
// SArray* g = GET_TABLEGROUP(pOperator->, 0);
|
||||||
|
// pOperator->pRuntimeEnv->current = taosArrayGetP(g, 0);
|
||||||
|
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
return pBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SExecTaskInfo* pTaskInfo) {
|
||||||
|
STableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableScanInfo));
|
||||||
|
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||||
|
if (pInfo == NULL || pOperator == NULL) {
|
||||||
|
pTaskInfo->code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->dataReader = dataReader;
|
||||||
|
pInfo->block.pDataBlock = taosArrayInit(1, sizeof(SColumnInfoData));
|
||||||
|
|
||||||
|
SColumnInfoData infoData = {0};
|
||||||
|
infoData.info.type = TSDB_DATA_TYPE_BINARY;
|
||||||
|
infoData.info.bytes = 1024;
|
||||||
|
infoData.info.colId = 0;
|
||||||
|
taosArrayPush(pInfo->block.pDataBlock, &infoData);
|
||||||
|
|
||||||
|
pOperator->name = "DataBlockInfoScanOperator";
|
||||||
|
// pOperator->operatorType = OP_TableBlockInfoScan;
|
||||||
|
pOperator->blockingOptr = false;
|
||||||
|
pOperator->status = OP_NOT_OPENED;
|
||||||
|
pOperator->_openFn = operatorDummyOpenFn;
|
||||||
|
pOperator->getNextFn = doBlockInfoScan;
|
||||||
|
|
||||||
|
pOperator->info = pInfo;
|
||||||
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
|
||||||
|
return pOperator;
|
||||||
|
|
||||||
|
_error:
|
||||||
|
taosMemoryFreeClear(pInfo);
|
||||||
|
taosMemoryFreeClear(pOperator);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void doClearBufferedBlocks(SStreamBlockScanInfo* pInfo) {
|
||||||
|
size_t total = taosArrayGetSize(pInfo->pBlockLists);
|
||||||
|
|
||||||
|
pInfo->validBlockIndex = 0;
|
||||||
|
for (int32_t i = 0; i < total; ++i) {
|
||||||
|
SSDataBlock* p = taosArrayGetP(pInfo->pBlockLists, i);
|
||||||
|
blockDataDestroy(p);
|
||||||
|
}
|
||||||
|
taosArrayClear(pInfo->pBlockLists);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
pTaskInfo->code = pOperator->_openFn(pOperator);
|
||||||
|
if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pInfo->blockType == STREAM_DATA_TYPE_SSDATA_BLOCK) {
|
||||||
|
size_t total = taosArrayGetSize(pInfo->pBlockLists);
|
||||||
|
if (pInfo->validBlockIndex >= total) {
|
||||||
|
doClearBufferedBlocks(pInfo);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t current = pInfo->validBlockIndex++;
|
||||||
|
return taosArrayGetP(pInfo->pBlockLists, current);
|
||||||
|
} else {
|
||||||
|
SDataBlockInfo* pBlockInfo = &pInfo->pRes->info;
|
||||||
|
blockDataCleanup(pInfo->pRes);
|
||||||
|
|
||||||
|
while (tqNextDataBlock(pInfo->readerHandle)) {
|
||||||
|
pTaskInfo->code = tqRetrieveDataBlockInfo(pInfo->readerHandle, pBlockInfo);
|
||||||
|
if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
|
||||||
|
terrno = pTaskInfo->code;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pBlockInfo->rows == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SArray* pCols = tqRetrieveDataBlock(pInfo->readerHandle);
|
||||||
|
|
||||||
|
int32_t numOfCols = pInfo->pRes->info.numOfCols;
|
||||||
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
|
SColumnInfoData* p = taosArrayGet(pCols, i);
|
||||||
|
SColMatchInfo* pColMatchInfo = taosArrayGet(pInfo->pColMatchInfo, i);
|
||||||
|
if (!pColMatchInfo->output) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(pColMatchInfo->colId == p->info.colId);
|
||||||
|
taosArraySet(pInfo->pRes->pDataBlock, pColMatchInfo->targetSlotId, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pInfo->pRes->pDataBlock == NULL) {
|
||||||
|
// TODO add log
|
||||||
|
pTaskInfo->code = terrno;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// record the scan action.
|
||||||
|
pInfo->numOfExec++;
|
||||||
|
pInfo->numOfRows += pBlockInfo->rows;
|
||||||
|
|
||||||
|
return (pBlockInfo->rows == 0) ? NULL : pInfo->pRes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock* pResBlock, SArray* pColList, SArray* pTableIdList, SExecTaskInfo* pTaskInfo) {
|
||||||
|
SStreamBlockScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamBlockScanInfo));
|
||||||
|
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||||
|
if (pInfo == NULL || pOperator == NULL) {
|
||||||
|
taosMemoryFreeClear(pInfo);
|
||||||
|
taosMemoryFreeClear(pOperator);
|
||||||
|
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t numOfOutput = taosArrayGetSize(pColList);
|
||||||
|
|
||||||
|
SArray* pColIds = taosArrayInit(4, sizeof(int16_t));
|
||||||
|
for(int32_t i = 0; i < numOfOutput; ++i) {
|
||||||
|
int16_t* id = taosArrayGet(pColList, i);
|
||||||
|
taosArrayPush(pColIds, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->pColMatchInfo = pColList;
|
||||||
|
|
||||||
|
// set the extract column id to streamHandle
|
||||||
|
tqReadHandleSetColIdList((STqReadHandle*)streamReadHandle, pColIds);
|
||||||
|
int32_t code = tqReadHandleSetTbUidList(streamReadHandle, pTableIdList);
|
||||||
|
if (code != 0) {
|
||||||
|
taosMemoryFreeClear(pInfo);
|
||||||
|
taosMemoryFreeClear(pOperator);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->pBlockLists = taosArrayInit(4, POINTER_BYTES);
|
||||||
|
if (pInfo->pBlockLists == NULL) {
|
||||||
|
taosMemoryFreeClear(pInfo);
|
||||||
|
taosMemoryFreeClear(pOperator);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->readerHandle = streamReadHandle;
|
||||||
|
pInfo->pRes = pResBlock;
|
||||||
|
|
||||||
|
pOperator->name = "StreamBlockScanOperator";
|
||||||
|
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN;
|
||||||
|
pOperator->blockingOptr = false;
|
||||||
|
pOperator->status = OP_NOT_OPENED;
|
||||||
|
pOperator->info = pInfo;
|
||||||
|
pOperator->numOfOutput = pResBlock->info.numOfCols;
|
||||||
|
pOperator->_openFn = operatorDummyOpenFn;
|
||||||
|
pOperator->getNextFn = doStreamBlockScan;
|
||||||
|
pOperator->closeFn = operatorDummyCloseFn;
|
||||||
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
|
||||||
|
return pOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroySysScanOperator(void* param, int32_t numOfOutput) {
|
||||||
|
SSysTableScanInfo* pInfo = (SSysTableScanInfo*)param;
|
||||||
|
tsem_destroy(&pInfo->ready);
|
||||||
|
blockDataDestroy(pInfo->pRes);
|
||||||
|
|
||||||
|
if (pInfo->type == TSDB_MGMT_TABLE_TABLE) {
|
||||||
|
metaCloseTbCursor(pInfo->pCur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EDealRes getDBNameFromConditionWalker(SNode* pNode, void* pContext) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
ENodeType nType = nodeType(pNode);
|
||||||
|
|
||||||
|
switch (nType) {
|
||||||
|
case QUERY_NODE_OPERATOR: {
|
||||||
|
SOperatorNode* node = (SOperatorNode*)pNode;
|
||||||
|
|
||||||
|
if (OP_TYPE_EQUAL == node->opType) {
|
||||||
|
*(int32_t*)pContext = 1;
|
||||||
|
return DEAL_RES_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(int32_t*)pContext = 0;
|
||||||
|
|
||||||
|
return DEAL_RES_IGNORE_CHILD;
|
||||||
|
}
|
||||||
|
case QUERY_NODE_COLUMN: {
|
||||||
|
if (1 != *(int32_t*)pContext) {
|
||||||
|
return DEAL_RES_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SColumnNode* node = (SColumnNode*)pNode;
|
||||||
|
if (TSDB_INS_USER_STABLES_DBNAME_COLID == node->colId) {
|
||||||
|
*(int32_t*)pContext = 2;
|
||||||
|
return DEAL_RES_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(int32_t*)pContext = 0;
|
||||||
|
return DEAL_RES_CONTINUE;
|
||||||
|
}
|
||||||
|
case QUERY_NODE_VALUE: {
|
||||||
|
if (2 != *(int32_t*)pContext) {
|
||||||
|
return DEAL_RES_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SValueNode* node = (SValueNode*)pNode;
|
||||||
|
char* dbName = nodesGetValueFromNode(node);
|
||||||
|
strncpy(pContext, varDataVal(dbName), varDataLen(dbName));
|
||||||
|
*((char*)pContext + varDataLen(dbName)) = 0;
|
||||||
|
return DEAL_RES_ERROR; // stop walk
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DEAL_RES_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getDBNameFromCondition(SNode* pCondition, char* dbName) {
|
||||||
|
if (NULL == pCondition) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodesWalkExpr(pCondition, getDBNameFromConditionWalker, dbName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t loadSysTableContentCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||||
|
SOperatorInfo* operator=(SOperatorInfo*) param;
|
||||||
|
SSysTableScanInfo* pScanResInfo = (SSysTableScanInfo*)operator->info;
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
pScanResInfo->pRsp = pMsg->pData;
|
||||||
|
|
||||||
|
SRetrieveMetaTableRsp* pRsp = pScanResInfo->pRsp;
|
||||||
|
pRsp->numOfRows = htonl(pRsp->numOfRows);
|
||||||
|
pRsp->useconds = htobe64(pRsp->useconds);
|
||||||
|
pRsp->handle = htobe64(pRsp->handle);
|
||||||
|
pRsp->compLen = htonl(pRsp->compLen);
|
||||||
|
} else {
|
||||||
|
operator->pTaskInfo->code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
tsem_post(&pScanResInfo->ready);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SSDataBlock* doFilterResult(SSysTableScanInfo* pInfo) {
|
||||||
|
if (pInfo->pCondition == NULL) {
|
||||||
|
return pInfo->pRes->info.rows == 0 ? NULL : pInfo->pRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
SFilterInfo* filter = NULL;
|
||||||
|
int32_t code = filterInitFromNode(pInfo->pCondition, &filter, 0);
|
||||||
|
|
||||||
|
SFilterColumnParam param1 = {.numOfCols = pInfo->pRes->info.numOfCols, .pDataBlock = pInfo->pRes->pDataBlock};
|
||||||
|
code = filterSetDataFromSlotId(filter, ¶m1);
|
||||||
|
|
||||||
|
int8_t* rowRes = NULL;
|
||||||
|
bool keep = filterExecute(filter, pInfo->pRes, &rowRes, NULL, param1.numOfCols);
|
||||||
|
|
||||||
|
SSDataBlock* px = createOneDataBlock(pInfo->pRes);
|
||||||
|
blockDataEnsureCapacity(px, pInfo->pRes->info.rows);
|
||||||
|
|
||||||
|
// TODO refactor
|
||||||
|
int32_t numOfRow = 0;
|
||||||
|
for (int32_t i = 0; i < pInfo->pRes->info.numOfCols; ++i) {
|
||||||
|
SColumnInfoData* pDest = taosArrayGet(px->pDataBlock, i);
|
||||||
|
SColumnInfoData* pSrc = taosArrayGet(pInfo->pRes->pDataBlock, i);
|
||||||
|
|
||||||
|
numOfRow = 0;
|
||||||
|
for (int32_t j = 0; j < pInfo->pRes->info.rows; ++j) {
|
||||||
|
if (rowRes[j] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
colDataAppend(pDest, numOfRow, colDataGetData(pSrc, j), false);
|
||||||
|
numOfRow += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
px->info.rows = numOfRow;
|
||||||
|
pInfo->pRes = px;
|
||||||
|
|
||||||
|
return pInfo->pRes->info.rows == 0 ? NULL : pInfo->pRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator, bool* newgroup) {
|
||||||
|
// build message and send to mnode to fetch the content of system tables.
|
||||||
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
|
SSysTableScanInfo* pInfo = pOperator->info;
|
||||||
|
|
||||||
|
// retrieve local table list info from vnode
|
||||||
|
if (pInfo->type == TSDB_MGMT_TABLE_TABLE) {
|
||||||
|
if (pInfo->pCur == NULL) {
|
||||||
|
pInfo->pCur = metaOpenTbCursor(pInfo->readHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
blockDataCleanup(pInfo->pRes);
|
||||||
|
|
||||||
|
int32_t tableNameSlotId = 1;
|
||||||
|
SColumnInfoData* pTableNameCol = taosArrayGet(pInfo->pRes->pDataBlock, tableNameSlotId);
|
||||||
|
|
||||||
|
char* name = NULL;
|
||||||
|
int32_t numOfRows = 0;
|
||||||
|
|
||||||
|
char n[TSDB_TABLE_NAME_LEN] = {0};
|
||||||
|
while ((name = metaTbCursorNext(pInfo->pCur)) != NULL) {
|
||||||
|
STR_TO_VARSTR(n, name);
|
||||||
|
colDataAppend(pTableNameCol, numOfRows, n, false);
|
||||||
|
numOfRows += 1;
|
||||||
|
if (numOfRows >= pInfo->capacity) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pInfo->pRes->info.numOfCols; ++i) {
|
||||||
|
if (i == tableNameSlotId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SColumnInfoData* pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, i);
|
||||||
|
int64_t tmp = 0;
|
||||||
|
char t[10] = {0};
|
||||||
|
STR_TO_VARSTR(t, "_"); //TODO
|
||||||
|
if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
|
||||||
|
colDataAppend(pColInfoData, numOfRows, t, false);
|
||||||
|
} else {
|
||||||
|
colDataAppend(pColInfoData, numOfRows, (char*)&tmp, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->loadInfo.totalRows += numOfRows;
|
||||||
|
pInfo->pRes->info.rows = numOfRows;
|
||||||
|
|
||||||
|
// pInfo->elapsedTime;
|
||||||
|
// pInfo->totalBytes;
|
||||||
|
return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes;
|
||||||
|
} else { // load the meta from mnode of the given epset
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t startTs = taosGetTimestampUs();
|
||||||
|
|
||||||
|
pInfo->req.type = pInfo->type;
|
||||||
|
strncpy(pInfo->req.tb, tNameGetTableName(&pInfo->name), tListLen(pInfo->req.tb));
|
||||||
|
if (pInfo->showRewrite) {
|
||||||
|
char dbName[TSDB_DB_NAME_LEN] = {0};
|
||||||
|
getDBNameFromCondition(pInfo->pCondition, dbName);
|
||||||
|
sprintf(pInfo->req.db, "%d.%s", pInfo->accountId, dbName);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t contLen = tSerializeSRetrieveTableReq(NULL, 0, &pInfo->req);
|
||||||
|
char* buf1 = taosMemoryCalloc(1, contLen);
|
||||||
|
tSerializeSRetrieveTableReq(buf1, contLen, &pInfo->req);
|
||||||
|
|
||||||
|
// send the fetch remote task result reques
|
||||||
|
SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
|
||||||
|
if (NULL == pMsgSendInfo) {
|
||||||
|
qError("%s prepare message %d failed", GET_TASKID(pTaskInfo), (int32_t)sizeof(SMsgSendInfo));
|
||||||
|
pTaskInfo->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pMsgSendInfo->param = pOperator;
|
||||||
|
pMsgSendInfo->msgInfo.pData = buf1;
|
||||||
|
pMsgSendInfo->msgInfo.len = contLen;
|
||||||
|
pMsgSendInfo->msgType = TDMT_MND_SYSTABLE_RETRIEVE;
|
||||||
|
pMsgSendInfo->fp = loadSysTableContentCb;
|
||||||
|
|
||||||
|
int64_t transporterId = 0;
|
||||||
|
int32_t code = asyncSendMsgToServer(pInfo->pTransporter, &pInfo->epSet, &transporterId, pMsgSendInfo);
|
||||||
|
tsem_wait(&pInfo->ready);
|
||||||
|
|
||||||
|
if (pTaskInfo->code) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRetrieveMetaTableRsp* pRsp = pInfo->pRsp;
|
||||||
|
pInfo->req.showId = pRsp->handle;
|
||||||
|
|
||||||
|
if (pRsp->numOfRows == 0 || pRsp->completed) {
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRsp->numOfRows == 0) {
|
||||||
|
// qDebug("%s vgId:%d, taskID:0x%"PRIx64" %d of total completed, rowsOfSource:%"PRIu64", totalRows:%"PRIu64"
|
||||||
|
// try next",
|
||||||
|
// GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->taskId, pExchangeInfo->current + 1,
|
||||||
|
// pDataInfo->totalRows, pExchangeInfo->totalRows);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRetrieveMetaTableRsp* pTableRsp = pInfo->pRsp;
|
||||||
|
setSDataBlockFromFetchRsp(pInfo->pRes, &pInfo->loadInfo, pTableRsp->numOfRows, pTableRsp->data, pTableRsp->compLen,
|
||||||
|
pOperator->numOfOutput, startTs, NULL, pInfo->scanCols);
|
||||||
|
|
||||||
|
return doFilterResult(pInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SOperatorInfo* createSysTableScanOperatorInfo(void* pSysTableReadHandle, SSDataBlock* pResBlock, const SName* pName,
|
||||||
|
SNode* pCondition, SEpSet epset, SArray* colList,
|
||||||
|
SExecTaskInfo* pTaskInfo, bool showRewrite, int32_t accountId) {
|
||||||
|
SSysTableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SSysTableScanInfo));
|
||||||
|
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||||
|
if (pInfo == NULL || pOperator == NULL) {
|
||||||
|
taosMemoryFreeClear(pInfo);
|
||||||
|
taosMemoryFreeClear(pOperator);
|
||||||
|
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->accountId = accountId;
|
||||||
|
pInfo->showRewrite = showRewrite;
|
||||||
|
pInfo->pRes = pResBlock;
|
||||||
|
pInfo->capacity = 4096;
|
||||||
|
pInfo->pCondition = pCondition;
|
||||||
|
pInfo->scanCols = colList;
|
||||||
|
|
||||||
|
// TODO remove it
|
||||||
|
int32_t tableType = 0;
|
||||||
|
const char* name = tNameGetTableName(pName);
|
||||||
|
if (strncasecmp(name, TSDB_INS_TABLE_USER_DATABASES, tListLen(pName->tname)) == 0) {
|
||||||
|
tableType = TSDB_MGMT_TABLE_DB;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_USER_USERS, tListLen(pName->tname)) == 0) {
|
||||||
|
tableType = TSDB_MGMT_TABLE_USER;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_DNODES, tListLen(pName->tname)) == 0) {
|
||||||
|
tableType = TSDB_MGMT_TABLE_DNODE;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_MNODES, tListLen(pName->tname)) == 0) {
|
||||||
|
tableType = TSDB_MGMT_TABLE_MNODE;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_MODULES, tListLen(pName->tname)) == 0) {
|
||||||
|
tableType = TSDB_MGMT_TABLE_MODULE;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_QNODES, tListLen(pName->tname)) == 0) {
|
||||||
|
tableType = TSDB_MGMT_TABLE_QNODE;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_USER_FUNCTIONS, tListLen(pName->tname)) == 0) {
|
||||||
|
tableType = TSDB_MGMT_TABLE_FUNC;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_USER_INDEXES, tListLen(pName->tname)) == 0) {
|
||||||
|
// tableType = TSDB_MGMT_TABLE_INDEX;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_USER_STABLES, tListLen(pName->tname)) == 0) {
|
||||||
|
tableType = TSDB_MGMT_TABLE_STB;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_USER_STREAMS, tListLen(pName->tname)) == 0) {
|
||||||
|
tableType = TSDB_MGMT_TABLE_STREAMS;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_USER_TABLES, tListLen(pName->tname)) == 0) {
|
||||||
|
tableType = TSDB_MGMT_TABLE_TABLE;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_VGROUPS, tListLen(pName->tname)) == 0) {
|
||||||
|
tableType = TSDB_MGMT_TABLE_VGROUP;
|
||||||
|
} else if (strncasecmp(name, TSDB_INS_TABLE_USER_TABLE_DISTRIBUTED, tListLen(pName->tname)) == 0) {
|
||||||
|
// tableType = TSDB_MGMT_TABLE_DIST;
|
||||||
|
} else {
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
tNameAssign(&pInfo->name, pName);
|
||||||
|
pInfo->type = tableType;
|
||||||
|
if (pInfo->type == TSDB_MGMT_TABLE_TABLE) {
|
||||||
|
pInfo->readHandle = pSysTableReadHandle;
|
||||||
|
blockDataEnsureCapacity(pInfo->pRes, pInfo->capacity);
|
||||||
|
} else {
|
||||||
|
tsem_init(&pInfo->ready, 0, 0);
|
||||||
|
pInfo->epSet = epset;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
{ // todo refactor
|
||||||
|
SRpcInit rpcInit;
|
||||||
|
memset(&rpcInit, 0, sizeof(rpcInit));
|
||||||
|
rpcInit.localPort = 0;
|
||||||
|
rpcInit.label = "DB-META";
|
||||||
|
rpcInit.numOfThreads = 1;
|
||||||
|
rpcInit.cfp = qProcessFetchRsp;
|
||||||
|
rpcInit.sessions = tsMaxConnections;
|
||||||
|
rpcInit.connType = TAOS_CONN_CLIENT;
|
||||||
|
rpcInit.user = (char*)"root";
|
||||||
|
rpcInit.idleTime = tsShellActivityTimer * 1000;
|
||||||
|
rpcInit.ckey = "key";
|
||||||
|
rpcInit.spi = 1;
|
||||||
|
rpcInit.secret = (char*)"dcc5bed04851fec854c035b2e40263b6";
|
||||||
|
|
||||||
|
pInfo->pTransporter = rpcOpen(&rpcInit);
|
||||||
|
if (pInfo->pTransporter == NULL) {
|
||||||
|
return NULL; // todo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
pOperator->name = "SysTableScanOperator";
|
||||||
|
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN;
|
||||||
|
pOperator->blockingOptr = false;
|
||||||
|
pOperator->status = OP_NOT_OPENED;
|
||||||
|
pOperator->info = pInfo;
|
||||||
|
pOperator->numOfOutput = pResBlock->info.numOfCols;
|
||||||
|
pOperator->getNextFn = doSysTableScan;
|
||||||
|
pOperator->closeFn = destroySysScanOperator;
|
||||||
|
pOperator->pTaskInfo = pTaskInfo;
|
||||||
|
|
||||||
|
return pOperator;
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ typedef struct SHNode {
|
||||||
char data[];
|
char data[];
|
||||||
} SHNode;
|
} SHNode;
|
||||||
|
|
||||||
typedef struct SSHashObj {
|
struct SSHashObj {
|
||||||
SHNode **hashList;
|
SHNode **hashList;
|
||||||
size_t capacity; // number of slots
|
size_t capacity; // number of slots
|
||||||
int64_t size; // number of elements in hash table
|
int64_t size; // number of elements in hash table
|
||||||
|
@ -45,7 +45,7 @@ typedef struct SSHashObj {
|
||||||
_equal_fn_t equalFp; // equal function
|
_equal_fn_t equalFp; // equal function
|
||||||
int32_t keyLen;
|
int32_t keyLen;
|
||||||
int32_t dataLen;
|
int32_t dataLen;
|
||||||
} SSHashObj;
|
};
|
||||||
|
|
||||||
static FORCE_INLINE int32_t taosHashCapacity(int32_t length) {
|
static FORCE_INLINE int32_t taosHashCapacity(int32_t length) {
|
||||||
int32_t len = MIN(length, HASH_MAX_CAPACITY);
|
int32_t len = MIN(length, HASH_MAX_CAPACITY);
|
||||||
|
@ -107,7 +107,7 @@ static SHNode *doCreateHashNode(const void *key, size_t keyLen, const void *pDat
|
||||||
return pNewNode;
|
return pNewNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void taosHashTableResize(SSHashObj *pHashObj) {
|
static void taosHashTableResize(SSHashObj *pHashObj) {
|
||||||
if (!HASH_NEED_RESIZE(pHashObj)) {
|
if (!HASH_NEED_RESIZE(pHashObj)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,31 +26,34 @@ bool functionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||||
void functionFinalize(SqlFunctionCtx *pCtx);
|
void functionFinalize(SqlFunctionCtx *pCtx);
|
||||||
|
|
||||||
bool getCountFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
bool getCountFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
void countFunction(SqlFunctionCtx *pCtx);
|
int32_t countFunction(SqlFunctionCtx *pCtx);
|
||||||
|
|
||||||
bool getSumFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
bool getSumFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
void sumFunction(SqlFunctionCtx *pCtx);
|
int32_t sumFunction(SqlFunctionCtx *pCtx);
|
||||||
|
|
||||||
bool minFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
bool minFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||||
bool maxFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
bool maxFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||||
bool getMinmaxFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
bool getMinmaxFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
void minFunction(SqlFunctionCtx* pCtx);
|
int32_t minFunction(SqlFunctionCtx* pCtx);
|
||||||
void maxFunction(SqlFunctionCtx *pCtx);
|
int32_t maxFunction(SqlFunctionCtx *pCtx);
|
||||||
|
|
||||||
bool getStddevFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
bool getStddevFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
bool stddevFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
bool stddevFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||||
void stddevFunction(SqlFunctionCtx* pCtx);
|
int32_t stddevFunction(SqlFunctionCtx* pCtx);
|
||||||
void stddevFinalize(SqlFunctionCtx* pCtx);
|
void stddevFinalize(SqlFunctionCtx* pCtx);
|
||||||
|
|
||||||
bool getPercentileFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
bool getPercentileFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
bool percentileFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
bool percentileFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||||
void percentileFunction(SqlFunctionCtx *pCtx);
|
int32_t percentileFunction(SqlFunctionCtx *pCtx);
|
||||||
|
void percentileFinalize(SqlFunctionCtx* pCtx);
|
||||||
|
|
||||||
|
bool getDiffFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
|
bool diffFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo);
|
||||||
|
int32_t diffFunction(SqlFunctionCtx *pCtx);
|
||||||
|
|
||||||
bool getFirstLastFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
bool getFirstLastFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
void firstFunction(SqlFunctionCtx *pCtx);
|
int32_t firstFunction(SqlFunctionCtx *pCtx);
|
||||||
void lastFunction(SqlFunctionCtx *pCtx);
|
int32_t lastFunction(SqlFunctionCtx *pCtx);
|
||||||
|
|
||||||
void valFunction(SqlFunctionCtx *pCtx);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,6 @@ typedef struct SInterpInfoDetail {
|
||||||
int8_t primaryCol;
|
int8_t primaryCol;
|
||||||
} SInterpInfoDetail;
|
} SInterpInfoDetail;
|
||||||
|
|
||||||
#define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowEntryInfo)))
|
|
||||||
|
|
||||||
typedef struct STwaInfo {
|
typedef struct STwaInfo {
|
||||||
int8_t hasResult; // flag to denote has value
|
int8_t hasResult; // flag to denote has value
|
||||||
double dOutput;
|
double dOutput;
|
||||||
|
|
|
@ -63,74 +63,74 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.finalizeFunc = functionFinalize
|
.finalizeFunc = functionFinalize
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "stddev",
|
.name = "stddev",
|
||||||
.type = FUNCTION_TYPE_STDDEV,
|
.type = FUNCTION_TYPE_STDDEV,
|
||||||
.classification = FUNC_MGT_AGG_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC,
|
||||||
.checkFunc = stubCheckAndGetResultType,
|
.checkFunc = stubCheckAndGetResultType,
|
||||||
.getEnvFunc = getStddevFuncEnv,
|
.getEnvFunc = getStddevFuncEnv,
|
||||||
.initFunc = stddevFunctionSetup,
|
.initFunc = stddevFunctionSetup,
|
||||||
.processFunc = stddevFunction,
|
.processFunc = stddevFunction,
|
||||||
.finalizeFunc = stddevFinalize
|
.finalizeFunc = stddevFinalize
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "percentile",
|
.name = "percentile",
|
||||||
.type = FUNCTION_TYPE_PERCENTILE,
|
.type = FUNCTION_TYPE_PERCENTILE,
|
||||||
.classification = FUNC_MGT_AGG_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC,
|
||||||
.checkFunc = stubCheckAndGetResultType,
|
.checkFunc = stubCheckAndGetResultType,
|
||||||
.getEnvFunc = getMinmaxFuncEnv,
|
.getEnvFunc = getPercentileFuncEnv,
|
||||||
.initFunc = maxFunctionSetup,
|
.initFunc = percentileFunctionSetup,
|
||||||
.processFunc = maxFunction,
|
.processFunc = percentileFunction,
|
||||||
.finalizeFunc = functionFinalize
|
.finalizeFunc = percentileFinalize
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "apercentile",
|
.name = "apercentile",
|
||||||
.type = FUNCTION_TYPE_APERCENTILE,
|
.type = FUNCTION_TYPE_APERCENTILE,
|
||||||
.classification = FUNC_MGT_AGG_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC,
|
||||||
.checkFunc = stubCheckAndGetResultType,
|
.checkFunc = stubCheckAndGetResultType,
|
||||||
.getEnvFunc = getMinmaxFuncEnv,
|
.getEnvFunc = getMinmaxFuncEnv,
|
||||||
.initFunc = maxFunctionSetup,
|
.initFunc = maxFunctionSetup,
|
||||||
.processFunc = maxFunction,
|
.processFunc = maxFunction,
|
||||||
.finalizeFunc = functionFinalize
|
.finalizeFunc = functionFinalize
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "top",
|
.name = "top",
|
||||||
.type = FUNCTION_TYPE_TOP,
|
.type = FUNCTION_TYPE_TOP,
|
||||||
.classification = FUNC_MGT_AGG_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC,
|
||||||
.checkFunc = stubCheckAndGetResultType,
|
.checkFunc = stubCheckAndGetResultType,
|
||||||
.getEnvFunc = getMinmaxFuncEnv,
|
.getEnvFunc = getMinmaxFuncEnv,
|
||||||
.initFunc = maxFunctionSetup,
|
.initFunc = maxFunctionSetup,
|
||||||
.processFunc = maxFunction,
|
.processFunc = maxFunction,
|
||||||
.finalizeFunc = functionFinalize
|
.finalizeFunc = functionFinalize
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "bottom",
|
.name = "bottom",
|
||||||
.type = FUNCTION_TYPE_BOTTOM,
|
.type = FUNCTION_TYPE_BOTTOM,
|
||||||
.classification = FUNC_MGT_AGG_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC,
|
||||||
.checkFunc = stubCheckAndGetResultType,
|
.checkFunc = stubCheckAndGetResultType,
|
||||||
.getEnvFunc = getMinmaxFuncEnv,
|
.getEnvFunc = getMinmaxFuncEnv,
|
||||||
.initFunc = maxFunctionSetup,
|
.initFunc = maxFunctionSetup,
|
||||||
.processFunc = maxFunction,
|
.processFunc = maxFunction,
|
||||||
.finalizeFunc = functionFinalize
|
.finalizeFunc = functionFinalize
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "spread",
|
.name = "spread",
|
||||||
.type = FUNCTION_TYPE_SPREAD,
|
.type = FUNCTION_TYPE_SPREAD,
|
||||||
.classification = FUNC_MGT_AGG_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC,
|
||||||
.checkFunc = stubCheckAndGetResultType,
|
.checkFunc = stubCheckAndGetResultType,
|
||||||
.getEnvFunc = getMinmaxFuncEnv,
|
.getEnvFunc = getMinmaxFuncEnv,
|
||||||
.initFunc = maxFunctionSetup,
|
.initFunc = maxFunctionSetup,
|
||||||
.processFunc = maxFunction,
|
.processFunc = maxFunction,
|
||||||
.finalizeFunc = functionFinalize
|
.finalizeFunc = functionFinalize
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "last_row",
|
.name = "last_row",
|
||||||
.type = FUNCTION_TYPE_LAST_ROW,
|
.type = FUNCTION_TYPE_LAST_ROW,
|
||||||
.classification = FUNC_MGT_AGG_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC,
|
||||||
.checkFunc = stubCheckAndGetResultType,
|
.checkFunc = stubCheckAndGetResultType,
|
||||||
.getEnvFunc = getMinmaxFuncEnv,
|
.getEnvFunc = getMinmaxFuncEnv,
|
||||||
.initFunc = maxFunctionSetup,
|
.initFunc = maxFunctionSetup,
|
||||||
.processFunc = maxFunction,
|
.processFunc = maxFunction,
|
||||||
.finalizeFunc = functionFinalize
|
.finalizeFunc = functionFinalize
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "first",
|
.name = "first",
|
||||||
|
@ -152,6 +152,16 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.processFunc = lastFunction,
|
.processFunc = lastFunction,
|
||||||
.finalizeFunc = functionFinalize
|
.finalizeFunc = functionFinalize
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "diff",
|
||||||
|
.type = FUNCTION_TYPE_DIFF,
|
||||||
|
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC,
|
||||||
|
.checkFunc = stubCheckAndGetResultType,
|
||||||
|
.getEnvFunc = getDiffFuncEnv,
|
||||||
|
.initFunc = diffFunctionSetup,
|
||||||
|
.processFunc = diffFunction,
|
||||||
|
.finalizeFunc = functionFinalize
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "abs",
|
.name = "abs",
|
||||||
.type = FUNCTION_TYPE_ABS,
|
.type = FUNCTION_TYPE_ABS,
|
||||||
|
@ -377,7 +387,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.type = FUNCTION_TYPE_ROWTS,
|
.type = FUNCTION_TYPE_ROWTS,
|
||||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC,
|
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC,
|
||||||
.checkFunc = stubCheckAndGetResultType,
|
.checkFunc = stubCheckAndGetResultType,
|
||||||
.getEnvFunc = NULL,
|
.getEnvFunc = getTimePseudoFuncEnv,
|
||||||
.initFunc = NULL,
|
.initFunc = NULL,
|
||||||
.sprocessFunc = NULL,
|
.sprocessFunc = NULL,
|
||||||
.finalizeFunc = NULL
|
.finalizeFunc = NULL
|
||||||
|
@ -459,9 +469,11 @@ const int32_t funcMgtBuiltinsNum = (sizeof(funcMgtBuiltins) / sizeof(SBuiltinFun
|
||||||
int32_t stubCheckAndGetResultType(SFunctionNode* pFunc) {
|
int32_t stubCheckAndGetResultType(SFunctionNode* pFunc) {
|
||||||
switch(pFunc->funcType) {
|
switch(pFunc->funcType) {
|
||||||
case FUNCTION_TYPE_WDURATION:
|
case FUNCTION_TYPE_WDURATION:
|
||||||
case FUNCTION_TYPE_COUNT:
|
case FUNCTION_TYPE_COUNT: {
|
||||||
pFunc->node.resType = (SDataType){.bytes = sizeof(int64_t), .type = TSDB_DATA_TYPE_BIGINT};
|
pFunc->node.resType = (SDataType){.bytes = sizeof(int64_t), .type = TSDB_DATA_TYPE_BIGINT};
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case FUNCTION_TYPE_SUM: {
|
case FUNCTION_TYPE_SUM: {
|
||||||
SColumnNode* pParam = nodesListGetNode(pFunc->pParameterList, 0);
|
SColumnNode* pParam = nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
int32_t paraType = pParam->node.resType.type;
|
int32_t paraType = pParam->node.resType.type;
|
||||||
|
@ -480,6 +492,8 @@ int32_t stubCheckAndGetResultType(SFunctionNode* pFunc) {
|
||||||
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[resType].bytes, .type = resType };
|
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[resType].bytes, .type = resType };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case FUNCTION_TYPE_DIFF:
|
||||||
case FUNCTION_TYPE_FIRST:
|
case FUNCTION_TYPE_FIRST:
|
||||||
case FUNCTION_TYPE_LAST:
|
case FUNCTION_TYPE_LAST:
|
||||||
case FUNCTION_TYPE_MIN:
|
case FUNCTION_TYPE_MIN:
|
||||||
|
@ -490,10 +504,11 @@ int32_t stubCheckAndGetResultType(SFunctionNode* pFunc) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case FUNCTION_TYPE_QENDTS:
|
case FUNCTION_TYPE_ROWTS:
|
||||||
case FUNCTION_TYPE_QSTARTTS:
|
case FUNCTION_TYPE_QSTARTTS:
|
||||||
case FUNCTION_TYPE_WENDTS:
|
case FUNCTION_TYPE_QENDTS:
|
||||||
case FUNCTION_TYPE_WSTARTTS: {
|
case FUNCTION_TYPE_WSTARTTS:
|
||||||
|
case FUNCTION_TYPE_WENDTS:{
|
||||||
pFunc->node.resType = (SDataType){.bytes = sizeof(int64_t), .type = TSDB_DATA_TYPE_TIMESTAMP};
|
pFunc->node.resType = (SDataType){.bytes = sizeof(int64_t), .type = TSDB_DATA_TYPE_TIMESTAMP};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -508,6 +523,7 @@ int32_t stubCheckAndGetResultType(SFunctionNode* pFunc) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case FUNCTION_TYPE_PERCENTILE:
|
||||||
case FUNCTION_TYPE_STDDEV:
|
case FUNCTION_TYPE_STDDEV:
|
||||||
case FUNCTION_TYPE_SIN:
|
case FUNCTION_TYPE_SIN:
|
||||||
case FUNCTION_TYPE_COS:
|
case FUNCTION_TYPE_COS:
|
||||||
|
@ -531,36 +547,35 @@ int32_t stubCheckAndGetResultType(SFunctionNode* pFunc) {
|
||||||
case FUNCTION_TYPE_CONCAT:
|
case FUNCTION_TYPE_CONCAT:
|
||||||
case FUNCTION_TYPE_CONCAT_WS: {
|
case FUNCTION_TYPE_CONCAT_WS: {
|
||||||
int32_t paraType, paraBytes = 0;
|
int32_t paraType, paraBytes = 0;
|
||||||
|
bool typeSet = false;
|
||||||
for (int32_t i = 0; i < pFunc->pParameterList->length; ++i) {
|
for (int32_t i = 0; i < pFunc->pParameterList->length; ++i) {
|
||||||
SColumnNode* pParam = nodesListGetNode(pFunc->pParameterList, i);
|
SColumnNode* pParam = nodesListGetNode(pFunc->pParameterList, i);
|
||||||
paraBytes += pParam->node.resType.bytes;
|
if (pParam->node.type == QUERY_NODE_COLUMN) {
|
||||||
paraType = pParam->node.resType.type;
|
if (typeSet == false) {
|
||||||
|
paraType = pParam->node.resType.type;
|
||||||
|
typeSet = true;
|
||||||
|
} else {
|
||||||
|
//columns have to be the same type
|
||||||
|
if (paraType != pParam->node.resType.type) {
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
paraBytes += pParam->node.resType.bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pFunc->pParameterList->length; ++i) {
|
||||||
|
SColumnNode* pParam = nodesListGetNode(pFunc->pParameterList, i);
|
||||||
|
if (pParam->node.type == QUERY_NODE_VALUE) {
|
||||||
|
if (paraType == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
paraBytes += pParam->node.resType.bytes * TSDB_NCHAR_SIZE;
|
||||||
|
} else {
|
||||||
|
paraBytes += pParam->node.resType.bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pFunc->node.resType = (SDataType) { .bytes = paraBytes, .type = paraType };
|
pFunc->node.resType = (SDataType) { .bytes = paraBytes, .type = paraType };
|
||||||
break;
|
break;
|
||||||
//int32_t paraTypeFirst, totalBytes = 0, sepBytes = 0;
|
|
||||||
//int32_t firstParamIndex = 0;
|
|
||||||
//if (pFunc->funcType == FUNCTION_TYPE_CONCAT_WS) {
|
|
||||||
// firstParamIndex = 1;
|
|
||||||
// SColumnNode* pSep = nodesListGetNode(pFunc->pParameterList, 0);
|
|
||||||
// sepBytes = pSep->node.resType.type;
|
|
||||||
//}
|
|
||||||
//for (int32_t i = firstParamIndex; i < pFunc->pParameterList->length; ++i) {
|
|
||||||
// SColumnNode* pParam = nodesListGetNode(pFunc->pParameterList, i);
|
|
||||||
// int32_t paraType = pParam->node.resType.type;
|
|
||||||
// if (i == firstParamIndex) {
|
|
||||||
// paraTypeFirst = paraType;
|
|
||||||
// }
|
|
||||||
// if (paraType != paraTypeFirst) {
|
|
||||||
// return TSDB_CODE_FAILED;
|
|
||||||
// }
|
|
||||||
// //TODO: for constants also needs numOfRows
|
|
||||||
// totalBytes += pParam->node.resType.bytes;
|
|
||||||
//}
|
|
||||||
////TODO: need to get numOfRows to decide how much space separator needed. Currently set to 100.
|
|
||||||
//totalBytes += sepBytes * (pFunc->pParameterList->length - 2) * 100;
|
|
||||||
//pFunc->node.resType = (SDataType) { .bytes = totalBytes, .type = paraTypeFirst };
|
|
||||||
//break;
|
|
||||||
}
|
}
|
||||||
case FUNCTION_TYPE_LOWER:
|
case FUNCTION_TYPE_LOWER:
|
||||||
case FUNCTION_TYPE_UPPER:
|
case FUNCTION_TYPE_UPPER:
|
||||||
|
@ -574,7 +589,6 @@ int32_t stubCheckAndGetResultType(SFunctionNode* pFunc) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case FUNCTION_TYPE_ROWTS:
|
|
||||||
case FUNCTION_TYPE_TBNAME: {
|
case FUNCTION_TYPE_TBNAME: {
|
||||||
// todo
|
// todo
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -65,7 +65,7 @@ bool getCountFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
||||||
* count function does need the finalize, if data is missing, the default value, which is 0, is used
|
* count function does need the finalize, if data is missing, the default value, which is 0, is used
|
||||||
* count function does not use the pCtx->interResBuf to keep the intermediate buffer
|
* count function does not use the pCtx->interResBuf to keep the intermediate buffer
|
||||||
*/
|
*/
|
||||||
void countFunction(SqlFunctionCtx *pCtx) {
|
int32_t countFunction(SqlFunctionCtx *pCtx) {
|
||||||
int32_t numOfElem = 0;
|
int32_t numOfElem = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -111,7 +111,7 @@ void countFunction(SqlFunctionCtx *pCtx) {
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
void sumFunction(SqlFunctionCtx *pCtx) {
|
int32_t sumFunction(SqlFunctionCtx *pCtx) {
|
||||||
int32_t numOfElem = 0;
|
int32_t numOfElem = 0;
|
||||||
|
|
||||||
// Only the pre-computing information loaded and actual data does not loaded
|
// Only the pre-computing information loaded and actual data does not loaded
|
||||||
|
@ -432,12 +432,12 @@ int32_t doMinMaxHelper(SqlFunctionCtx *pCtx, int32_t isMinFunc) {
|
||||||
return numOfElems;
|
return numOfElems;
|
||||||
}
|
}
|
||||||
|
|
||||||
void minFunction(SqlFunctionCtx *pCtx) {
|
int32_t minFunction(SqlFunctionCtx *pCtx) {
|
||||||
int32_t numOfElems = doMinMaxHelper(pCtx, 1);
|
int32_t numOfElems = doMinMaxHelper(pCtx, 1);
|
||||||
SET_VAL(GET_RES_INFO(pCtx), numOfElems, 1);
|
SET_VAL(GET_RES_INFO(pCtx), numOfElems, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void maxFunction(SqlFunctionCtx *pCtx) {
|
int32_t maxFunction(SqlFunctionCtx *pCtx) {
|
||||||
int32_t numOfElems = doMinMaxHelper(pCtx, 0);
|
int32_t numOfElems = doMinMaxHelper(pCtx, 0);
|
||||||
SET_VAL(GET_RES_INFO(pCtx), numOfElems, 1);
|
SET_VAL(GET_RES_INFO(pCtx), numOfElems, 1);
|
||||||
}
|
}
|
||||||
|
@ -475,12 +475,11 @@ bool stddevFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stddevFunction(SqlFunctionCtx* pCtx) {
|
int32_t stddevFunction(SqlFunctionCtx* pCtx) {
|
||||||
int32_t numOfElem = 0;
|
int32_t numOfElem = 0;
|
||||||
|
|
||||||
// Only the pre-computing information loaded and actual data does not loaded
|
// Only the pre-computing information loaded and actual data does not loaded
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
SColumnDataAgg* pAgg = pInput->pColumnDataAgg[0];
|
|
||||||
int32_t type = pInput->pData[0]->info.type;
|
int32_t type = pInput->pData[0]->info.type;
|
||||||
|
|
||||||
SStddevRes* pStddevRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
SStddevRes* pStddevRes = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||||
|
@ -601,6 +600,7 @@ void stddevFinalize(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct SPercentileInfo {
|
typedef struct SPercentileInfo {
|
||||||
|
double result;
|
||||||
tMemBucket *pMemBucket;
|
tMemBucket *pMemBucket;
|
||||||
int32_t stage;
|
int32_t stage;
|
||||||
double minval;
|
double minval;
|
||||||
|
@ -627,19 +627,24 @@ bool percentileFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultI
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void percentileFunction(SqlFunctionCtx *pCtx) {
|
int32_t percentileFunction(SqlFunctionCtx *pCtx) {
|
||||||
int32_t notNullElems = 0;
|
int32_t notNullElems = 0;
|
||||||
#if 0
|
SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
|
||||||
SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
|
||||||
|
|
||||||
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
|
SColumnDataAgg *pAgg = pInput->pColumnDataAgg[0];
|
||||||
|
|
||||||
|
SColumnInfoData *pCol = pInput->pData[0];
|
||||||
|
int32_t type = pCol->info.type;
|
||||||
|
|
||||||
|
SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
if (pCtx->currentStage == REPEAT_SCAN && pInfo->stage == 0) {
|
if (pCtx->currentStage == REPEAT_SCAN && pInfo->stage == 0) {
|
||||||
pInfo->stage += 1;
|
pInfo->stage += 1;
|
||||||
|
|
||||||
// all data are null, set it completed
|
// all data are null, set it completed
|
||||||
if (pInfo->numOfElems == 0) {
|
if (pInfo->numOfElems == 0) {
|
||||||
pResInfo->complete = true;
|
pResInfo->complete = true;
|
||||||
return;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
pInfo->pMemBucket = tMemBucketCreate(pCtx->inputBytes, pCtx->inputType, pInfo->minval, pInfo->maxval);
|
pInfo->pMemBucket = tMemBucketCreate(pCtx->inputBytes, pCtx->inputType, pInfo->minval, pInfo->maxval);
|
||||||
}
|
}
|
||||||
|
@ -647,19 +652,17 @@ void percentileFunction(SqlFunctionCtx *pCtx) {
|
||||||
|
|
||||||
// the first stage, only acquire the min/max value
|
// the first stage, only acquire the min/max value
|
||||||
if (pInfo->stage == 0) {
|
if (pInfo->stage == 0) {
|
||||||
if (pCtx->preAggVals.isSet) {
|
if (pCtx->input.colDataAggIsSet) {
|
||||||
double tmin = 0.0, tmax = 0.0;
|
double tmin = 0.0, tmax = 0.0;
|
||||||
if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType)) {
|
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
||||||
tmin = (double)GET_INT64_VAL(&pCtx->preAggVals.statis.min);
|
tmin = (double)GET_INT64_VAL(&pAgg->min);
|
||||||
tmax = (double)GET_INT64_VAL(&pCtx->preAggVals.statis.max);
|
tmax = (double)GET_INT64_VAL(&pAgg->max);
|
||||||
} else if (IS_FLOAT_TYPE(pCtx->inputType)) {
|
} else if (IS_FLOAT_TYPE(type)) {
|
||||||
tmin = GET_DOUBLE_VAL(&pCtx->preAggVals.statis.min);
|
tmin = GET_DOUBLE_VAL(&pAgg->min);
|
||||||
tmax = GET_DOUBLE_VAL(&pCtx->preAggVals.statis.max);
|
tmax = GET_DOUBLE_VAL(&pAgg->max);
|
||||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(pCtx->inputType)) {
|
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||||
tmin = (double)GET_UINT64_VAL(&pCtx->preAggVals.statis.min);
|
tmin = (double)GET_UINT64_VAL(&pAgg->min);
|
||||||
tmax = (double)GET_UINT64_VAL(&pCtx->preAggVals.statis.max);
|
tmax = (double)GET_UINT64_VAL(&pAgg->max);
|
||||||
} else {
|
|
||||||
assert(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GET_DOUBLE_VAL(&pInfo->minval) > tmin) {
|
if (GET_DOUBLE_VAL(&pInfo->minval) > tmin) {
|
||||||
|
@ -670,17 +673,19 @@ void percentileFunction(SqlFunctionCtx *pCtx) {
|
||||||
SET_DOUBLE_VAL(&pInfo->maxval, tmax);
|
SET_DOUBLE_VAL(&pInfo->maxval, tmax);
|
||||||
}
|
}
|
||||||
|
|
||||||
pInfo->numOfElems += (pCtx->size - pCtx->preAggVals.statis.numOfNull);
|
pInfo->numOfElems += (pInput->numOfRows - pAgg->numOfNull);
|
||||||
} else {
|
} else {
|
||||||
for (int32_t i = 0; i < pCtx->size; ++i) {
|
// check the valid data one by one
|
||||||
char *data = GET_INPUT_DATA(pCtx, i);
|
int32_t start = pInput->startRowIndex;
|
||||||
if (pCtx->hasNull && isNull(data, pCtx->inputType)) {
|
for (int32_t i = start; i < pInput->numOfRows + start; ++i) {
|
||||||
|
if (colDataIsNull_f(pCol->nullbitmap, i)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *data = colDataGetData(pCol, i);
|
||||||
|
|
||||||
double v = 0;
|
double v = 0;
|
||||||
GET_TYPED_DATA(v, double, pCtx->inputType, data);
|
GET_TYPED_DATA(v, double, pCtx->inputType, data);
|
||||||
|
|
||||||
if (v < GET_DOUBLE_VAL(&pInfo->minval)) {
|
if (v < GET_DOUBLE_VAL(&pInfo->minval)) {
|
||||||
SET_DOUBLE_VAL(&pInfo->minval, v);
|
SET_DOUBLE_VAL(&pInfo->minval, v);
|
||||||
}
|
}
|
||||||
|
@ -693,24 +698,40 @@ void percentileFunction(SqlFunctionCtx *pCtx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the second stage, calculate the true percentile value
|
// the second stage, calculate the true percentile value
|
||||||
for (int32_t i = 0; i < pCtx->size; ++i) {
|
int32_t start = pInput->startRowIndex;
|
||||||
char *data = GET_INPUT_DATA(pCtx, i);
|
for (int32_t i = start; i < pInput->numOfRows + start; ++i) {
|
||||||
if (pCtx->hasNull && isNull(data, pCtx->inputType)) {
|
if (colDataIsNull_f(pCol->nullbitmap, i)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *data = colDataGetData(pCol, i);
|
||||||
|
|
||||||
notNullElems += 1;
|
notNullElems += 1;
|
||||||
tMemBucketPut(pInfo->pMemBucket, data, 1);
|
tMemBucketPut(pInfo->pMemBucket, data, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_VAL(pCtx, notNullElems, 1);
|
SET_VAL(pResInfo, notNullElems, 1);
|
||||||
pResInfo->hasResult = DATA_SET_FLAG;
|
pResInfo->hasResult = DATA_SET_FLAG;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
// TODO set the correct parameter.
|
||||||
|
void percentileFinalize(SqlFunctionCtx* pCtx) {
|
||||||
|
double v = 50;//pCtx->param[0].nType == TSDB_DATA_TYPE_INT ? pCtx->param[0].i64 : pCtx->param[0].dKey;
|
||||||
|
|
||||||
|
SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
|
SPercentileInfo* ppInfo = (SPercentileInfo *) GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
|
tMemBucket * pMemBucket = ppInfo->pMemBucket;
|
||||||
|
if (pMemBucket != NULL && pMemBucket->total > 0) { // check for null
|
||||||
|
SET_DOUBLE_VAL(&ppInfo->result, getPercentile(pMemBucket, v));
|
||||||
|
}
|
||||||
|
|
||||||
|
tMemBucketDestroy(pMemBucket);
|
||||||
|
functionFinalize(pCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getFirstLastFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
bool getFirstLastFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
||||||
|
@ -721,9 +742,9 @@ bool getFirstLastFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
||||||
|
|
||||||
// TODO fix this
|
// TODO fix this
|
||||||
// This ordinary first function only handle the data block in ascending order
|
// This ordinary first function only handle the data block in ascending order
|
||||||
void firstFunction(SqlFunctionCtx *pCtx) {
|
int32_t firstFunction(SqlFunctionCtx *pCtx) {
|
||||||
if (pCtx->order == TSDB_ORDER_DESC) {
|
if (pCtx->order == TSDB_ORDER_DESC) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t numOfElems = 0;
|
int32_t numOfElems = 0;
|
||||||
|
@ -737,7 +758,7 @@ void firstFunction(SqlFunctionCtx *pCtx) {
|
||||||
// All null data column, return directly.
|
// All null data column, return directly.
|
||||||
if (pInput->colDataAggIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) {
|
if (pInput->colDataAggIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) {
|
||||||
ASSERT(pInputCol->hasNull == true);
|
ASSERT(pInputCol->hasNull == true);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for the first not null data
|
// Check for the first not null data
|
||||||
|
@ -764,9 +785,9 @@ void firstFunction(SqlFunctionCtx *pCtx) {
|
||||||
SET_VAL(pResInfo, numOfElems, 1);
|
SET_VAL(pResInfo, numOfElems, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lastFunction(SqlFunctionCtx *pCtx) {
|
int32_t lastFunction(SqlFunctionCtx *pCtx) {
|
||||||
if (pCtx->order != TSDB_ORDER_DESC) {
|
if (pCtx->order != TSDB_ORDER_DESC) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t numOfElems = 0;
|
int32_t numOfElems = 0;
|
||||||
|
@ -775,13 +796,12 @@ void lastFunction(SqlFunctionCtx *pCtx) {
|
||||||
char* buf = GET_ROWCELL_INTERBUF(pResInfo);
|
char* buf = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
|
|
||||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||||
|
|
||||||
// All null data column, return directly.
|
// All null data column, return directly.
|
||||||
if (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows) {
|
if (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows) {
|
||||||
ASSERT(pInputCol->hasNull == true);
|
ASSERT(pInputCol->hasNull == true);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pCtx->order == TSDB_ORDER_DESC) {
|
if (pCtx->order == TSDB_ORDER_DESC) {
|
||||||
|
@ -826,10 +846,242 @@ void lastFunction(SqlFunctionCtx *pCtx) {
|
||||||
SET_VAL(pResInfo, numOfElems, 1);
|
SET_VAL(pResInfo, numOfElems, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void valFunction(SqlFunctionCtx *pCtx) {
|
typedef struct SDiffInfo {
|
||||||
SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
|
bool hasPrev;
|
||||||
char* buf = GET_ROWCELL_INTERBUF(pResInfo);
|
bool includeNull;
|
||||||
|
bool ignoreNegative;
|
||||||
|
bool firstOutput;
|
||||||
|
union { int64_t i64; double d64;} prev;
|
||||||
|
} SDiffInfo;
|
||||||
|
|
||||||
SColumnInfoData* pInputCol = pCtx->input.pData[0];
|
bool getDiffFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
||||||
memcpy(buf, pInputCol->pData, pInputCol->info.bytes);
|
pEnv->calcMemSize = sizeof(SDiffInfo);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool diffFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo) {
|
||||||
|
if (!functionSetup(pCtx, pResInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDiffInfo* pDiffInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
pDiffInfo->hasPrev = false;
|
||||||
|
pDiffInfo->prev.i64 = 0;
|
||||||
|
pDiffInfo->ignoreNegative = false; // TODO set correct param
|
||||||
|
pDiffInfo->includeNull = false;
|
||||||
|
pDiffInfo->firstOutput = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t diffFunction(SqlFunctionCtx *pCtx) {
|
||||||
|
SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
|
SDiffInfo *pDiffInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
|
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||||
|
|
||||||
|
bool isFirstBlock = (pDiffInfo->hasPrev == false);
|
||||||
|
int32_t numOfElems = 0;
|
||||||
|
|
||||||
|
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order);
|
||||||
|
// int32_t i = (pCtx->order == TSDB_ORDER_ASC) ? 0 : pCtx->size - 1;
|
||||||
|
|
||||||
|
SColumnInfoData* pTsOutput = pCtx->pTsOutput;
|
||||||
|
TSKEY* tsList = (int64_t*)pInput->pPTS->pData;
|
||||||
|
|
||||||
|
int32_t startOffset = pCtx->offset;
|
||||||
|
switch (pInputCol->info.type) {
|
||||||
|
case TSDB_DATA_TYPE_INT: {
|
||||||
|
SColumnInfoData *pOutput = (SColumnInfoData *)pCtx->pOutput;
|
||||||
|
for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; i += step) {
|
||||||
|
|
||||||
|
int32_t pos = startOffset + (isFirstBlock? (numOfElems-1):numOfElems);
|
||||||
|
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||||
|
if (pDiffInfo->includeNull) {
|
||||||
|
colDataSetNull_f(pOutput->nullbitmap, pos);
|
||||||
|
if (tsList != NULL) {
|
||||||
|
colDataAppendInt64(pTsOutput, pos, &tsList[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
numOfElems += 1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t v = *(int32_t*) colDataGetData(pInputCol, i);
|
||||||
|
if (pDiffInfo->hasPrev) {
|
||||||
|
int32_t delta = (int32_t)(v - pDiffInfo->prev.i64); // direct previous may be null
|
||||||
|
if (delta < 0 && pDiffInfo->ignoreNegative) {
|
||||||
|
colDataSetNull_f(pOutput->nullbitmap, pos);
|
||||||
|
} else {
|
||||||
|
colDataAppendInt32(pOutput, pos, &delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pTsOutput != NULL) {
|
||||||
|
colDataAppendInt64(pTsOutput, pos, &tsList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pDiffInfo->prev.i64 = v;
|
||||||
|
pDiffInfo->hasPrev = true;
|
||||||
|
numOfElems++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_BIGINT: {
|
||||||
|
SColumnInfoData *pOutput = (SColumnInfoData *)pCtx->pOutput;
|
||||||
|
for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; i += step) {
|
||||||
|
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t v = 0;
|
||||||
|
if (pDiffInfo->hasPrev) {
|
||||||
|
v = *(int64_t*) colDataGetData(pInputCol, i);
|
||||||
|
int64_t delta = (int64_t)(v - pDiffInfo->prev.i64); // direct previous may be null
|
||||||
|
if (pDiffInfo->ignoreNegative) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *(pOutput++) = delta;
|
||||||
|
// *pTimestamp = (tsList != NULL)? tsList[i]:0;
|
||||||
|
//
|
||||||
|
// pOutput += 1;
|
||||||
|
// pTimestamp += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pDiffInfo->prev.i64 = v;
|
||||||
|
pDiffInfo->hasPrev = true;
|
||||||
|
numOfElems++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE: {
|
||||||
|
double *pData = (double *)data;
|
||||||
|
double *pOutput = (double *)pCtx->pOutput;
|
||||||
|
|
||||||
|
for (; i < pCtx->size && i >= 0; i += step) {
|
||||||
|
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((pDiffInfo->ignoreNegative) && (pData[i] < 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDiffInfo->hasPrev) { // initial value is not set yet
|
||||||
|
SET_DOUBLE_VAL(pOutput, pData[i] - pDiffInfo->d64Prev); // direct previous may be null
|
||||||
|
*pTimestamp = (tsList != NULL)? tsList[i]:0;
|
||||||
|
pOutput += 1;
|
||||||
|
pTimestamp += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pDiffInfo->d64Prev = pData[i];
|
||||||
|
pDiffInfo->hasPrev = true;
|
||||||
|
numOfElems++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_FLOAT: {
|
||||||
|
float *pData = (float *)data;
|
||||||
|
float *pOutput = (float *)pCtx->pOutput;
|
||||||
|
|
||||||
|
for (; i < pCtx->size && i >= 0; i += step) {
|
||||||
|
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((pDiffInfo->ignoreNegative) && (pData[i] < 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDiffInfo->hasPrev) { // initial value is not set yet
|
||||||
|
*pOutput = (float)(pData[i] - pDiffInfo->d64Prev); // direct previous may be null
|
||||||
|
*pTimestamp = (tsList != NULL)? tsList[i]:0;
|
||||||
|
pOutput += 1;
|
||||||
|
pTimestamp += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pDiffInfo->d64Prev = pData[i];
|
||||||
|
pDiffInfo->hasPrev = true;
|
||||||
|
numOfElems++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT: {
|
||||||
|
int16_t *pData = (int16_t *)data;
|
||||||
|
int16_t *pOutput = (int16_t *)pCtx->pOutput;
|
||||||
|
|
||||||
|
for (; i < pCtx->size && i >= 0; i += step) {
|
||||||
|
if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((pDiffInfo->ignoreNegative) && (pData[i] < 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDiffInfo->hasPrev) { // initial value is not set yet
|
||||||
|
*pOutput = (int16_t)(pData[i] - pDiffInfo->i64Prev); // direct previous may be null
|
||||||
|
*pTimestamp = (tsList != NULL)? tsList[i]:0;
|
||||||
|
pOutput += 1;
|
||||||
|
pTimestamp += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pDiffInfo->i64Prev = pData[i];
|
||||||
|
pDiffInfo->hasPrev = true;
|
||||||
|
numOfElems++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TSDB_DATA_TYPE_TINYINT: {
|
||||||
|
int8_t *pData = (int8_t *)data;
|
||||||
|
int8_t *pOutput = (int8_t *)pCtx->pOutput;
|
||||||
|
|
||||||
|
for (; i < pCtx->size && i >= 0; i += step) {
|
||||||
|
if (pCtx->hasNull && isNull((char *)&pData[i], pCtx->inputType)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((pDiffInfo->ignoreNegative) && (pData[i] < 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDiffInfo->hasPrev) { // initial value is not set yet
|
||||||
|
*pOutput = (int8_t)(pData[i] - pDiffInfo->i64Prev); // direct previous may be null
|
||||||
|
*pTimestamp = (tsList != NULL)? tsList[i]:0;
|
||||||
|
pOutput += 1;
|
||||||
|
pTimestamp += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pDiffInfo->i64Prev = pData[i];
|
||||||
|
pDiffInfo->hasPrev = true;
|
||||||
|
numOfElems++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
// qError("error input type");
|
||||||
|
}
|
||||||
|
|
||||||
|
// initial value is not set yet
|
||||||
|
if (!pDiffInfo->hasPrev || numOfElems <= 0) {
|
||||||
|
/*
|
||||||
|
* 1. current block and blocks before are full of null
|
||||||
|
* 2. current block may be null value
|
||||||
|
*/
|
||||||
|
assert(pCtx->hasNull);
|
||||||
|
} else {
|
||||||
|
// for (int t = 0; t < pCtx->tagInfo.numOfTagCols; ++t) {
|
||||||
|
// SqlFunctionCtx* tagCtx = pCtx->tagInfo.pTagCtxList[t];
|
||||||
|
// if (tagCtx->functionId == TSDB_FUNC_TAG_DUMMY) {
|
||||||
|
// aAggs[TSDB_FUNC_TAGPRJ].xFunction(tagCtx);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
int32_t forwardStep = (isFirstBlock) ? numOfElems - 1 : numOfElems;
|
||||||
|
return forwardStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,10 @@ bool fmIsScalarFunc(int32_t funcId) {
|
||||||
return isSpecificClassifyFunc(funcId, FUNC_MGT_SCALAR_FUNC);
|
return isSpecificClassifyFunc(funcId, FUNC_MGT_SCALAR_FUNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fmIsPseudoColumnFunc(int32_t funcId) {
|
||||||
|
return isSpecificClassifyFunc(funcId, FUNC_MGT_PSEUDO_COLUMN_FUNC);
|
||||||
|
}
|
||||||
|
|
||||||
bool fmIsWindowPseudoColumnFunc(int32_t funcId) {
|
bool fmIsWindowPseudoColumnFunc(int32_t funcId) {
|
||||||
return isSpecificClassifyFunc(funcId, FUNC_MGT_WINDOW_PC_FUNC);
|
return isSpecificClassifyFunc(funcId, FUNC_MGT_WINDOW_PC_FUNC);
|
||||||
}
|
}
|
||||||
|
@ -112,6 +116,11 @@ bool fmIsWindowClauseFunc(int32_t funcId) {
|
||||||
return fmIsAggFunc(funcId) || fmIsWindowPseudoColumnFunc(funcId);
|
return fmIsAggFunc(funcId) || fmIsWindowPseudoColumnFunc(funcId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fmIsNonstandardSQLFunc(int32_t funcId) {
|
||||||
|
return isSpecificClassifyFunc(funcId, FUNC_MGT_NONSTANDARD_SQL_FUNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void fmFuncMgtDestroy() {
|
void fmFuncMgtDestroy() {
|
||||||
void* m = gFunMgtService.pFuncNameHashTable;
|
void* m = gFunMgtService.pFuncNameHashTable;
|
||||||
if (m != NULL && atomic_val_compare_exchange_ptr((void**)&gFunMgtService.pFuncNameHashTable, m, 0) == m) {
|
if (m != NULL && atomic_val_compare_exchange_ptr((void**)&gFunMgtService.pFuncNameHashTable, m, 0) == m) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue