feature/qnode
This commit is contained in:
parent
7602f91612
commit
27a3a1d782
|
@ -915,11 +915,19 @@ typedef struct {
|
|||
char data[];
|
||||
} SRetrieveMetaTableRsp;
|
||||
|
||||
typedef struct SExplainExecInfo {
|
||||
uint64_t startupCost;
|
||||
uint64_t totalCost;
|
||||
uint64_t numOfRows;
|
||||
} SExplainExecInfo;
|
||||
|
||||
typedef struct {
|
||||
int32_t numOfItems;
|
||||
char data[];
|
||||
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 {
|
||||
char fqdn[TSDB_FQDN_LEN]; // end point, hostname:port
|
||||
|
|
|
@ -19,17 +19,11 @@
|
|||
|
||||
typedef struct SExplainCtx SExplainCtx;
|
||||
|
||||
typedef struct SExplainExecInfo {
|
||||
uint64_t startupCost;
|
||||
uint64_t totalCost;
|
||||
uint64_t numOfRows;
|
||||
} SExplainExecInfo;
|
||||
|
||||
int32_t qExecCommand(SNode* pStmt, SRetrieveTableRsp** pRsp);
|
||||
|
||||
int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp);
|
||||
int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int32_t startTs);
|
||||
int32_t qExecExplainEnd(SExplainCtx *pCtx);
|
||||
int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp);
|
||||
int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp);
|
||||
void qExplainFreeCtx(SExplainCtx *pCtx);
|
||||
|
||||
|
|
|
@ -217,6 +217,7 @@ int32_t nodesStringToList(const char* pStr, SNodeList** pList);
|
|||
|
||||
int32_t nodesNodeToSQL(SNode *pNode, char *buf, int32_t bufSize, int32_t *len);
|
||||
char *nodesGetNameFromColumnNode(SNode *pNode);
|
||||
int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ void taosWLockLatch(SRWLatch *pLatch);
|
|||
void taosWUnLockLatch(SRWLatch *pLatch);
|
||||
void taosRLockLatch(SRWLatch *pLatch);
|
||||
void taosRUnLockLatch(SRWLatch *pLatch);
|
||||
int32_t taosWTryLockLatch(SRWLatch *pLatch);
|
||||
|
||||
// copy on read
|
||||
#define taosCorBeginRead(x) \
|
||||
|
|
|
@ -2787,6 +2787,48 @@ int32_t tDecodeSMqCMCommitOffsetReq(SCoder *decoder, SMqCMCommitOffsetReq *pReq)
|
|||
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 headLen = sizeof(SMsgHead);
|
||||
if (buf != NULL) {
|
||||
|
|
|
@ -26,39 +26,53 @@ extern "C" {
|
|||
#define EXPLAIN_MAX_GROUP_NUM 100
|
||||
|
||||
//newline area
|
||||
#define EXPLAIN_TAG_SCAN_FORMAT "Tag Scan on %s columns=%d width=%d"
|
||||
#define EXPLAIN_TBL_SCAN_FORMAT "Table Scan on %s columns=%d width=%d"
|
||||
#define EXPLAIN_SYSTBL_SCAN_FORMAT "System Table Scan on %s columns=%d width=%d"
|
||||
#define EXPLAIN_PROJECTION_FORMAT "Projection columns=%d width=%d"
|
||||
#define EXPLAIN_JOIN_FORMAT "%s between %d tables width=%d"
|
||||
#define EXPLAIN_AGG_FORMAT "Aggragate functions=%d"
|
||||
#define EXPLAIN_EXCHANGE_FORMAT "Data Exchange %d:1 width=%d"
|
||||
#define EXPLAIN_SORT_FORMAT "Sort on %d Column(s) width=%d"
|
||||
#define EXPLAIN_INTERVAL_FORMAT "Interval on Column %s functions=%d interval=%" PRId64 "%c offset=%" PRId64 "%c sliding=%" PRId64 "%c width=%d"
|
||||
#define EXPLAIN_SESSION_FORMAT "Session gap=%" PRId64 " functions=%d width=%d"
|
||||
#define EXPLAIN_TAG_SCAN_FORMAT "Tag Scan on %s"
|
||||
#define EXPLAIN_TBL_SCAN_FORMAT "Table Scan on %s"
|
||||
#define EXPLAIN_SYSTBL_SCAN_FORMAT "System Table Scan on %s"
|
||||
#define EXPLAIN_PROJECTION_FORMAT "Projection"
|
||||
#define EXPLAIN_JOIN_FORMAT "%s"
|
||||
#define EXPLAIN_AGG_FORMAT "Aggragate"
|
||||
#define EXPLAIN_EXCHANGE_FORMAT "Data Exchange %d:1"
|
||||
#define EXPLAIN_SORT_FORMAT "Sort"
|
||||
#define EXPLAIN_INTERVAL_FORMAT "Interval on Column %s"
|
||||
#define EXPLAIN_SESSION_FORMAT "Session"
|
||||
#define EXPLAIN_ORDER_FORMAT "Order: %s"
|
||||
#define EXPLAIN_FILTER_FORMAT "Filter: "
|
||||
#define EXPLAIN_FILL_FORMAT "Fill: %s"
|
||||
#define EXPLAIN_ON_CONDITIONS_FORMAT "Join Cond: "
|
||||
#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
|
||||
#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_LEFT_PARENTHESIS_FORMAT " ("
|
||||
#define EXPLAIN_RIGHT_PARENTHESIS_FORMAT ")"
|
||||
#define EXPLAIN_BLANK_FORMAT " "
|
||||
#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"
|
||||
|
||||
typedef struct SExplainGroup {
|
||||
int32_t nodeNum;
|
||||
int32_t physiPlanExecNum;
|
||||
int32_t physiPlanNum;
|
||||
int32_t physiPlanExecIdx;
|
||||
SRWLatch lock;
|
||||
SSubplan *plan;
|
||||
SArray *execInfo;
|
||||
SArray *nodeExecInfo; //Array<SExplainRsp>
|
||||
} SExplainGroup;
|
||||
|
||||
typedef struct SExplainResNode {
|
||||
SNodeList* pChildren;
|
||||
SPhysiNode* pNode;
|
||||
void* pExecInfo;
|
||||
SNodeList* pChildren;
|
||||
SPhysiNode* pNode;
|
||||
SArray* pExecInfo; // Array<SExplainExecInfo>
|
||||
} SExplainResNode;
|
||||
|
||||
typedef struct SQueryExplainRowInfo {
|
||||
|
@ -68,19 +82,21 @@ typedef struct SQueryExplainRowInfo {
|
|||
} SQueryExplainRowInfo;
|
||||
|
||||
typedef struct SExplainCtx {
|
||||
double ratio;
|
||||
bool verbose;
|
||||
EExplainMode mode;
|
||||
double ratio;
|
||||
bool verbose;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
#define EXPLAIN_ORDER_STRING(_order) ((TSDB_ORDER_ASC == _order) ? "Ascending" : "Descending")
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "plannodes.h"
|
||||
#include "commandInt.h"
|
||||
|
||||
int32_t qExplainGenerateResNode(SPhysiNode *pNode, void *pExecInfo, SExplainResNode **pRes);
|
||||
int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pRes);
|
||||
int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level);
|
||||
|
||||
|
||||
|
@ -48,12 +48,30 @@ void qExplainFreeCtx(SExplainCtx *pCtx) {
|
|||
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);
|
||||
taosArrayDestroy(pCtx->rows);
|
||||
taosMemoryFree(pCtx);
|
||||
}
|
||||
|
||||
int32_t qExplainInitCtx(SExplainCtx **pCtx, SHashObj *groupHash, bool verbose, double ratio) {
|
||||
int32_t qExplainInitCtx(SExplainCtx **pCtx, SHashObj *groupHash, bool verbose, double ratio, EExplainMode mode) {
|
||||
int32_t code = 0;
|
||||
SExplainCtx *ctx = taosMemoryCalloc(1, sizeof(SExplainCtx));
|
||||
if (NULL == ctx) {
|
||||
|
@ -73,6 +91,7 @@ int32_t qExplainInitCtx(SExplainCtx **pCtx, SHashObj *groupHash, bool verbose, d
|
|||
QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
ctx->mode = mode;
|
||||
ctx->verbose = verbose;
|
||||
ctx->ratio = ratio;
|
||||
ctx->tbuf = tbuf;
|
||||
|
@ -92,7 +111,7 @@ _return:
|
|||
QRY_RET(code);
|
||||
}
|
||||
|
||||
int32_t qExplainGenerateResChildren(SPhysiNode *pNode, void *pExecInfo, SNodeList **pChildren) {
|
||||
int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNodeList **pChildren) {
|
||||
int32_t tlen = 0;
|
||||
SNodeList *pPhysiChildren = NULL;
|
||||
|
||||
|
@ -164,20 +183,43 @@ int32_t qExplainGenerateResChildren(SPhysiNode *pNode, void *pExecInfo, SNodeLis
|
|||
SNode* node = NULL;
|
||||
SExplainResNode *pResNode = NULL;
|
||||
FOREACH(node, pPhysiChildren) {
|
||||
QRY_ERR_RET(qExplainGenerateResNode((SPhysiNode *)node, pExecInfo, &pResNode));
|
||||
QRY_ERR_RET(qExplainGenerateResNode((SPhysiNode *)node, group, &pResNode));
|
||||
QRY_ERR_RET(nodesListAppend(*pChildren, pResNode));
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qExplainGenerateResNode(SPhysiNode *pNode, void *pExecInfo, SExplainResNode **pResNode) {
|
||||
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) {
|
||||
*pResNode = NULL;
|
||||
qError("physical node is NULL");
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
|
||||
|
||||
SExplainResNode *resNode = taosMemoryCalloc(1, sizeof(SExplainResNode));
|
||||
if (NULL == resNode) {
|
||||
qError("calloc SPhysiNodeExplainRes failed");
|
||||
|
@ -186,8 +228,11 @@ int32_t qExplainGenerateResNode(SPhysiNode *pNode, void *pExecInfo, SExplainResN
|
|||
|
||||
int32_t code = 0;
|
||||
resNode->pNode = pNode;
|
||||
resNode->pExecInfo = pExecInfo;
|
||||
QRY_ERR_JRET(qExplainGenerateResChildren(pNode, pExecInfo, &resNode->pChildren));
|
||||
QRY_ERR_JRET(qExplainGenerateResNodeExecInfo(&resNode->pExecInfo, group));
|
||||
|
||||
QRY_ERR_JRET(qExplainGenerateResChildren(pNode, group, &resNode->pChildren));
|
||||
|
||||
++group->physiPlanNum;
|
||||
|
||||
*pResNode = resNode;
|
||||
|
||||
|
@ -200,7 +245,7 @@ _return:
|
|||
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;
|
||||
|
||||
EXPLAIN_ROW_APPEND("(exec info here)");
|
||||
|
@ -247,18 +292,33 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
switch (pNode->type) {
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: {
|
||||
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) {
|
||||
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);
|
||||
if (pTagScanNode->reverse) {
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_REVERSE_FORMAT, pTagScanNode->reverse);
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
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_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
@ -268,18 +328,33 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:{
|
||||
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) {
|
||||
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);
|
||||
if (pTblScanNode->scan.reverse) {
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_REVERSE_FORMAT, pTblScanNode->scan.reverse);
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
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_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
@ -299,18 +374,33 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:{
|
||||
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) {
|
||||
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);
|
||||
if (pSTblScanNode->scan.reverse) {
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_REVERSE_FORMAT, pSTblScanNode->scan.reverse);
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
|
||||
EXPLAIN_ROW_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
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_END();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
|
@ -327,14 +417,27 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:{
|
||||
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) {
|
||||
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();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
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) {
|
||||
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));
|
||||
|
@ -346,14 +449,27 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_JOIN:{
|
||||
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) {
|
||||
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();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
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) {
|
||||
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));
|
||||
|
@ -370,19 +486,31 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_AGG:{
|
||||
SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT, pAggNode->pAggFuncs->length);
|
||||
if (pAggNode->pGroupKeys) {
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_GROUPS_FORMAT, pAggNode->pGroupKeys->length);
|
||||
}
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->outputRowSize);
|
||||
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
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();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
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) {
|
||||
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));
|
||||
|
@ -400,14 +528,25 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
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) {
|
||||
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();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
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) {
|
||||
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));
|
||||
|
@ -421,14 +560,28 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SORT:{
|
||||
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) {
|
||||
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();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
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) {
|
||||
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));
|
||||
|
@ -440,18 +593,32 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:{
|
||||
SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->pTspk), pIntNode->window.pFuncs->length,
|
||||
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,
|
||||
pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->pTspk));
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
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();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
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) {
|
||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_FORMAT, getFillModeString(pIntNode->pFill->mode));
|
||||
EXPLAIN_ROW_END();
|
||||
|
@ -468,18 +635,36 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:{
|
||||
SSessionWinodwPhysiNode *pIntNode = (SSessionWinodwPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_SESSION_FORMAT, pIntNode->gap, pIntNode->window.pFuncs->length, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
|
||||
SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
|
||||
EXPLAIN_ROW_NEW(level, EXPLAIN_SESSION_FORMAT);
|
||||
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
|
||||
if (pResNode->pExecInfo) {
|
||||
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();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
|
||||
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);
|
||||
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();
|
||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||
}
|
||||
|
@ -523,7 +708,12 @@ int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level) {
|
|||
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
QRY_ERR_RET(qExplainGenerateResNode(group->plan->pNode, group->execInfo, &node));
|
||||
QRY_ERR_RET(qExplainGenerateResNode(group->plan->pNode, group, &node));
|
||||
|
||||
if (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));
|
||||
|
||||
|
@ -601,7 +791,7 @@ int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
|
|||
QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
QRY_ERR_JRET(qExplainInitCtx(&ctx, groupHash, pDag->explainInfo.verbose, pDag->explainInfo.ratio));
|
||||
QRY_ERR_JRET(qExplainInitCtx(&ctx, groupHash, pDag->explainInfo.verbose, pDag->explainInfo.ratio, pDag->explainInfo.mode));
|
||||
|
||||
for (int32_t i = 0; i < levelNum; ++i) {
|
||||
plans = (SNodeListNode *)nodesListGetNode(pDag->pSubplans, i);
|
||||
|
@ -625,7 +815,10 @@ int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
|
|||
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))) {
|
||||
qError("taosHashPut to explainGroupHash failed, taskIdx:%d", n);
|
||||
QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
|
@ -656,8 +849,70 @@ _return:
|
|||
}
|
||||
|
||||
|
||||
int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -666,10 +921,8 @@ int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
|
|||
SExplainCtx *pCtx = NULL;
|
||||
|
||||
QRY_ERR_RET(qExplainPrepareCtx(pDag, &pCtx));
|
||||
|
||||
QRY_ERR_JRET(qExplainAppendGroupResRows(pCtx, pCtx->rootGroupId, 0));
|
||||
|
||||
QRY_ERR_JRET(qExplainGetRspFromCtx(pCtx, pRsp));
|
||||
QRY_ERR_JRET(qExplainGenerateRsp(pCtx, pRsp));
|
||||
|
||||
_return:
|
||||
|
||||
|
@ -687,11 +940,19 @@ int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int32_t startTs)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qExecExplainEnd(SExplainCtx *pCtx) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ extern "C" {
|
|||
#include "thash.h"
|
||||
#include "tlockfree.h"
|
||||
#include "tpagedbuf.h"
|
||||
#include "tmsg.h"
|
||||
|
||||
struct SColumnFilterElem;
|
||||
|
||||
|
@ -160,7 +161,7 @@ typedef struct STaskCostInfo {
|
|||
|
||||
typedef struct SOperatorCostInfo {
|
||||
uint64_t openCost;
|
||||
uint64_t execCost;
|
||||
uint64_t totalCost;
|
||||
} SOperatorCostInfo;
|
||||
|
||||
// The basic query information extracted from the SQueryInfo tree to support the
|
||||
|
@ -714,6 +715,7 @@ int32_t getMaximumIdleDurationSec();
|
|||
void doInvokeUdf(struct SUdfInfo* pUdfInfo, SqlFunctionCtx* pCtx, int32_t idx, int32_t type);
|
||||
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 getOperatorExplainExecInfo(SOperatorInfo *operator, SExplainExecInfo **pRes, int32_t *capacity, int32_t *resNum);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -9523,11 +9523,27 @@ int32_t getOperatorExplainExecInfo(SOperatorInfo *operator, SExplainExecInfo **p
|
|||
|
||||
*pRes = taosMemoryRealloc(*pRes, (*capacity) * sizeof(SExplainExecInfo));
|
||||
if (NULL == *pRes) {
|
||||
qError("malloc %d failed", capacity * sizeof(SExplainExecInfo));
|
||||
qError("malloc %d failed", (*capacity) * (int32_t)sizeof(SExplainExecInfo));
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
(*pRes)[*resNum].numOfRows = operator->resultInfo.totalRows;
|
||||
(*pRes)[*resNum].startupCost = operator->cost.openCost;
|
||||
(*pRes)[*resNum].totalCost = operator->cost.totalCost;
|
||||
|
||||
++(*resNum);
|
||||
|
||||
int32_t code = 0;
|
||||
for (int32_t i = 0; i < operator->numOfDownstream; ++i) {
|
||||
code = getOperatorExplainExecInfo(operator->pDownstream[i], pRes, capacity, resNum);
|
||||
if (code) {
|
||||
taosMemoryFreeClear(*pRes);
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1052,4 +1052,26 @@ char *nodesGetNameFromColumnNode(SNode *pNode) {
|
|||
return ((SColumnNode *)pNode)->colName;
|
||||
}
|
||||
|
||||
int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots) {
|
||||
if (NULL == pSlots || pSlots->length <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SNode* pNode = NULL;
|
||||
int32_t num = 0;
|
||||
FOREACH(pNode, pSlots) {
|
||||
if (QUERY_NODE_SLOT_DESC != pNode->type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SSlotDescNode *descNode = (SSlotDescNode *)pNode;
|
||||
if (descNode->output) {
|
||||
++num;
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ extern "C" {
|
|||
#include "qworkerInt.h"
|
||||
#include "dataSinkMgt.h"
|
||||
|
||||
int32_t qwProcessQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg, int8_t taskType);
|
||||
int32_t qwProcessQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg, int8_t taskType, int8_t explain);
|
||||
int32_t qwProcessCQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg);
|
||||
int32_t qwProcessReady(QW_FPARAMS_DEF, SQWMsg *qwMsg);
|
||||
int32_t qwProcessFetch(QW_FPARAMS_DEF, SQWMsg *qwMsg);
|
||||
|
@ -38,6 +38,7 @@ void qwBuildFetchRsp(void *msg, SOutputData *input, int32_t len, bool qComple
|
|||
int32_t qwBuildAndSendCQueryMsg(QW_FPARAMS_DEF, SQWConnInfo *pConn);
|
||||
int32_t qwBuildAndSendReadyRsp(SQWConnInfo *pConn, int32_t code);
|
||||
int32_t qwBuildAndSendQueryRsp(SQWConnInfo *pConn, int32_t code);
|
||||
int32_t qwBuildAndSendExplainRsp(SQWConnInfo *pConn, SExplainExecInfo *execInfo, int32_t num);
|
||||
void qwFreeFetchRsp(void *msg);
|
||||
int32_t qwMallocFetchRsp(int32_t length, SRetrieveTableRsp **rsp);
|
||||
int32_t qwGetSchTasksStatus(SQWorkerMgmt *mgmt, uint64_t sId, SSchedulerStatusRsp **rsp);
|
||||
|
|
|
@ -549,7 +549,10 @@ int32_t qwHandleTaskComplete(QW_FPARAMS_DEF, SQWTaskCtx *ctx) {
|
|||
int32_t resNum = 0;
|
||||
QW_ERR_RET(qGetExplainExecInfo(ctx->taskHandle, &resNum, &execInfo));
|
||||
|
||||
QW_ERR_RET(qwBuildAndSendExplainRsp(&ctx->ctrlConnInfo, &rsp));
|
||||
SQWConnInfo connInfo = {0};
|
||||
connInfo.handle = ctx->ctrlConnInfo.handle;
|
||||
|
||||
QW_ERR_RET(qwBuildAndSendExplainRsp(&connInfo, execInfo, resNum));
|
||||
}
|
||||
|
||||
qwFreeTaskHandle(QW_FPARAMS(), taskHandle);
|
||||
|
|
|
@ -85,6 +85,27 @@ int32_t qwBuildAndSendReadyRsp(SQWConnInfo *pConn, int32_t code) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qwBuildAndSendExplainRsp(SQWConnInfo *pConn, SExplainExecInfo *execInfo, int32_t num) {
|
||||
SExplainRsp rsp = {.numOfPlans = num, .subplanInfo = execInfo};
|
||||
|
||||
int32_t contLen = tSerializeSExplainRsp(NULL, 0, &rsp);
|
||||
void *pRsp = rpcMallocCont(contLen);
|
||||
tSerializeSExplainRsp(pRsp, contLen, &rsp);
|
||||
|
||||
SRpcMsg rpcRsp = {
|
||||
.msgType = TDMT_VND_EXPLAIN_RSP,
|
||||
.handle = pConn->handle,
|
||||
.ahandle = pConn->ahandle,
|
||||
.pCont = pRsp,
|
||||
.contLen = contLen,
|
||||
.code = 0,
|
||||
};
|
||||
|
||||
tmsgSendRsp(&rpcRsp);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qwBuildAndSendHbRsp(SQWConnInfo *pConn, SSchedulerHbRsp *pStatus, int32_t code) {
|
||||
int32_t contLen = tSerializeSSchedulerHbRsp(NULL, 0, pStatus);
|
||||
void *pRsp = rpcMallocCont(contLen);
|
||||
|
|
|
@ -1043,6 +1043,19 @@ _return:
|
|||
SCH_RET(schProcessOnTaskFailure(pJob, pJob->fetchTask, code));
|
||||
}
|
||||
|
||||
int32_t schProcessOnExplainDone(SSchJob *pJob, SSchTask *pTask, SRetrieveTableRsp *pRsp) {
|
||||
SCH_TASK_DLOG("got explain rsp, rows:%d, complete:%d", htonl(pRsp->numOfRows), pRsp->completed);
|
||||
|
||||
atomic_store_32(&pJob->resNumOfRows, htonl(pRsp->numOfRows));
|
||||
atomic_store_ptr(&pJob->resData, pRsp);
|
||||
|
||||
SCH_SET_TASK_STATUS(pTask, JOB_TASK_STATUS_SUCCEED);
|
||||
|
||||
schProcessOnDataFetched(pJob);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// Note: no more task error processing, handled in function internal
|
||||
int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, char *msg, int32_t msgSize,
|
||||
int32_t rspCode) {
|
||||
|
@ -1061,7 +1074,7 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
case TDMT_VND_CREATE_TABLE_RSP: {
|
||||
SVCreateTbBatchRsp batchRsp = {0};
|
||||
if (msg) {
|
||||
tDeserializeSVCreateTbBatchRsp(msg, msgSize, &batchRsp);
|
||||
SCH_ERR_JRET(tDeserializeSVCreateTbBatchRsp(msg, msgSize, &batchRsp));
|
||||
if (batchRsp.rspList) {
|
||||
int32_t num = taosArrayGetSize(batchRsp.rspList);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
|
@ -1099,7 +1112,7 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
case TDMT_VND_QUERY_RSP: {
|
||||
SQueryTableRsp rsp = {0};
|
||||
if (msg) {
|
||||
tDeserializeSQueryTableRsp(msg, msgSize, &rsp);
|
||||
SCH_ERR_JRET(tDeserializeSQueryTableRsp(msg, msgSize, &rsp));
|
||||
SCH_ERR_JRET(rsp.code);
|
||||
}
|
||||
|
||||
|
@ -1126,13 +1139,11 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
break;
|
||||
}
|
||||
case TDMT_VND_EXPLAIN_RSP: {
|
||||
SExplainRsp *taskRsp = (SExplainRsp *)msg;
|
||||
|
||||
SCH_ERR_JRET(rspCode);
|
||||
if (NULL == msg) {
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
|
||||
if (!SCH_IS_EXPLAIN_JOB(pJob)) {
|
||||
SCH_TASK_ELOG("invalid msg received for none explain query, msg type:%s", TMSG_INFO(msgType));
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
|
@ -1140,22 +1151,20 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
|
||||
if (pJob->resData) {
|
||||
SCH_TASK_ELOG("explain result is already generated, res:%p", pJob->resData);
|
||||
taosMemoryFreeClear(taskRsp);
|
||||
SCH_ERR_JRET(TSDB_CODE_SCH_STATUS_ERROR);
|
||||
}
|
||||
|
||||
SExplainRsp rsp = {0};
|
||||
if (tDeserializeSExplainRsp(msg, msgSize, &rsp)) {
|
||||
taosMemoryFree(rsp.subplanInfo);
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
SRetrieveTableRsp *pRsp = NULL;
|
||||
SCH_ERR_JRET(qExplainUpdateExecInfo(pJob->explainCtx, taskRsp, pTask->plan->id.groupId, &pRsp));
|
||||
SCH_ERR_JRET(qExplainUpdateExecInfo(pJob->explainCtx, &rsp, pTask->plan->id.groupId, &pRsp));
|
||||
|
||||
if (pRsp) {
|
||||
atomic_store_ptr(&pJob->resData, pRsp);
|
||||
atomic_store_32(&pJob->resNumOfRows, htonl(pRsp->numOfRows));
|
||||
|
||||
SCH_SET_TASK_STATUS(pTask, JOB_TASK_STATUS_SUCCEED);
|
||||
|
||||
SCH_TASK_DLOG("got explain rsp, rows:%d, complete:%d", htonl(pRsp->numOfRows), pRsp->completed);
|
||||
|
||||
schProcessOnDataFetched(pJob);
|
||||
SCH_ERR_JRET(schProcessOnExplainDone(pJob, pTask, pRsp));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1168,8 +1177,13 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
|||
}
|
||||
|
||||
if (SCH_IS_EXPLAIN_JOB(pJob)) {
|
||||
if (rsp->completed) {
|
||||
SCH_ERR_JRET(qExecExplainEnd(pJob->explainCtx));
|
||||
if (rsp->completed) {
|
||||
SRetrieveTableRsp *pRsp = NULL;
|
||||
SCH_ERR_JRET(qExecExplainEnd(pJob->explainCtx, &pRsp));
|
||||
if (pRsp) {
|
||||
SCH_ERR_JRET(schProcessOnExplainDone(pJob, pTask, pRsp));
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1278,6 +1292,10 @@ int32_t schHandleReadyCallback(void *param, const SDataBuf *pMsg, int32_t code)
|
|||
return schHandleCallback(param, pMsg, TDMT_VND_RES_READY_RSP, code);
|
||||
}
|
||||
|
||||
int32_t schHandleExplainCallback(void *param, const SDataBuf *pMsg, int32_t code) {
|
||||
return schHandleCallback(param, pMsg, TDMT_VND_EXPLAIN_RSP, code);
|
||||
}
|
||||
|
||||
int32_t schHandleDropCallback(void *param, const SDataBuf *pMsg, int32_t code) {
|
||||
SSchTaskCallbackParam *pParam = (SSchTaskCallbackParam *)param;
|
||||
qDebug("QID:%" PRIx64 ",TID:%" PRIx64 " drop task rsp received, code:%x", pParam->queryId, pParam->taskId, code);
|
||||
|
@ -1366,6 +1384,9 @@ int32_t schGetCallbackFp(int32_t msgType, __async_send_cb_fn_t *fp) {
|
|||
case TDMT_VND_RES_READY:
|
||||
*fp = schHandleReadyCallback;
|
||||
break;
|
||||
case TDMT_VND_EXPLAIN:
|
||||
*fp = schHandleExplainCallback;
|
||||
break;
|
||||
case TDMT_VND_FETCH:
|
||||
*fp = schHandleFetchCallback;
|
||||
break;
|
||||
|
@ -1386,6 +1407,43 @@ int32_t schGetCallbackFp(int32_t msgType, __async_send_cb_fn_t *fp) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t schGenerateTaskCallBackAHandle(SSchJob *pJob, SSchTask *pTask, int32_t msgType, SMsgSendInfo **pMsgSendInfo) {
|
||||
int32_t code = 0;
|
||||
SMsgSendInfo *msgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
|
||||
if (NULL == msgSendInfo) {
|
||||
SCH_TASK_ELOG("calloc %d failed", (int32_t)sizeof(SMsgSendInfo));
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
SSchTaskCallbackParam *param = taosMemoryCalloc(1, sizeof(SSchTaskCallbackParam));
|
||||
if (NULL == param) {
|
||||
SCH_TASK_ELOG("calloc %d failed", (int32_t)sizeof(SSchTaskCallbackParam));
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
__async_send_cb_fn_t fp = NULL;
|
||||
SCH_ERR_JRET(schGetCallbackFp(msgType, &fp));
|
||||
|
||||
param->queryId = pJob->queryId;
|
||||
param->refId = pJob->refId;
|
||||
param->taskId = SCH_TASK_ID(pTask);
|
||||
param->transport = pJob->transport;
|
||||
|
||||
msgSendInfo->param = param;
|
||||
msgSendInfo->fp = fp;
|
||||
|
||||
*pMsgSendInfo = msgSendInfo;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
taosMemoryFree(param);
|
||||
taosMemoryFree(msgSendInfo);
|
||||
|
||||
SCH_RET(code);
|
||||
}
|
||||
|
||||
void schFreeRpcCtxVal(const void *arg) {
|
||||
if (NULL == arg) {
|
||||
return;
|
||||
|
@ -1472,8 +1530,8 @@ _return:
|
|||
|
||||
int32_t schMakeQueryRpcCtx(SSchJob *pJob, SSchTask *pTask, SRpcCtx *pCtx) {
|
||||
int32_t code = 0;
|
||||
SSchTaskCallbackParam *param = NULL;
|
||||
SMsgSendInfo *pMsgSendInfo = NULL;
|
||||
SMsgSendInfo *pReadyMsgSendInfo = NULL;
|
||||
SMsgSendInfo *pExplainMsgSendInfo = NULL;
|
||||
|
||||
pCtx->args = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
|
||||
if (NULL == pCtx->args) {
|
||||
|
@ -1481,31 +1539,18 @@ int32_t schMakeQueryRpcCtx(SSchJob *pJob, SSchTask *pTask, SRpcCtx *pCtx) {
|
|||
SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
|
||||
if (NULL == pMsgSendInfo) {
|
||||
SCH_TASK_ELOG("calloc %d failed", (int32_t)sizeof(SMsgSendInfo));
|
||||
SCH_ERR_JRET(schGenerateTaskCallBackAHandle(pJob, pTask, TDMT_VND_RES_READY, &pReadyMsgSendInfo));
|
||||
SCH_ERR_JRET(schGenerateTaskCallBackAHandle(pJob, pTask, TDMT_VND_EXPLAIN, &pExplainMsgSendInfo));
|
||||
|
||||
int32_t msgType = TDMT_VND_RES_READY_RSP;
|
||||
SRpcCtxVal ctxVal = {.val = pReadyMsgSendInfo, .clone = schCloneSMsgSendInfo, .freeFunc = schFreeRpcCtxVal};
|
||||
if (taosHashPut(pCtx->args, &msgType, sizeof(msgType), &ctxVal, sizeof(ctxVal))) {
|
||||
SCH_TASK_ELOG("taosHashPut msg %d to rpcCtx failed", msgType);
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
param = taosMemoryCalloc(1, sizeof(SSchTaskCallbackParam));
|
||||
if (NULL == param) {
|
||||
SCH_TASK_ELOG("calloc %d failed", (int32_t)sizeof(SSchTaskCallbackParam));
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
int32_t msgType = TDMT_VND_RES_READY_RSP;
|
||||
__async_send_cb_fn_t fp = NULL;
|
||||
SCH_ERR_JRET(schGetCallbackFp(TDMT_VND_RES_READY, &fp));
|
||||
|
||||
param->queryId = pJob->queryId;
|
||||
param->refId = pJob->refId;
|
||||
param->taskId = SCH_TASK_ID(pTask);
|
||||
param->transport = pJob->transport;
|
||||
|
||||
pMsgSendInfo->param = param;
|
||||
pMsgSendInfo->fp = fp;
|
||||
|
||||
SRpcCtxVal ctxVal = {.val = pMsgSendInfo, .clone = schCloneSMsgSendInfo, .freeFunc = schFreeRpcCtxVal};
|
||||
msgType = TDMT_VND_EXPLAIN_RSP;
|
||||
ctxVal.val = pExplainMsgSendInfo;
|
||||
if (taosHashPut(pCtx->args, &msgType, sizeof(msgType), &ctxVal, sizeof(ctxVal))) {
|
||||
SCH_TASK_ELOG("taosHashPut msg %d to rpcCtx failed", msgType);
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
|
@ -1518,8 +1563,16 @@ int32_t schMakeQueryRpcCtx(SSchJob *pJob, SSchTask *pTask, SRpcCtx *pCtx) {
|
|||
_return:
|
||||
|
||||
taosHashCleanup(pCtx->args);
|
||||
taosMemoryFreeClear(param);
|
||||
taosMemoryFreeClear(pMsgSendInfo);
|
||||
|
||||
if (pReadyMsgSendInfo) {
|
||||
taosMemoryFreeClear(pReadyMsgSendInfo->param);
|
||||
taosMemoryFreeClear(pReadyMsgSendInfo);
|
||||
}
|
||||
|
||||
if (pExplainMsgSendInfo) {
|
||||
taosMemoryFreeClear(pExplainMsgSendInfo->param);
|
||||
taosMemoryFreeClear(pExplainMsgSendInfo);
|
||||
}
|
||||
|
||||
SCH_RET(code);
|
||||
}
|
||||
|
@ -1702,32 +1755,13 @@ int32_t schAsyncSendMsg(SSchJob *pJob, SSchTask *pTask, void *transport, SEpSet
|
|||
|
||||
SSchTrans *trans = (SSchTrans *)transport;
|
||||
|
||||
SMsgSendInfo *pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
|
||||
if (NULL == pMsgSendInfo) {
|
||||
SCH_TASK_ELOG("calloc %d failed", (int32_t)sizeof(SMsgSendInfo));
|
||||
SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
SMsgSendInfo *pMsgSendInfo = NULL;
|
||||
SCH_ERR_JRET(schGenerateTaskCallBackAHandle(pJob, pTask, msgType, &pMsgSendInfo));
|
||||
|
||||
SSchTaskCallbackParam *param = taosMemoryCalloc(1, sizeof(SSchTaskCallbackParam));
|
||||
if (NULL == param) {
|
||||
SCH_TASK_ELOG("calloc %d failed", (int32_t)sizeof(SSchTaskCallbackParam));
|
||||
SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
__async_send_cb_fn_t fp = NULL;
|
||||
SCH_ERR_JRET(schGetCallbackFp(msgType, &fp));
|
||||
|
||||
param->queryId = pJob->queryId;
|
||||
param->refId = pJob->refId;
|
||||
param->taskId = SCH_TASK_ID(pTask);
|
||||
param->transport = trans->transInst;
|
||||
|
||||
pMsgSendInfo->param = param;
|
||||
pMsgSendInfo->msgInfo.pData = msg;
|
||||
pMsgSendInfo->msgInfo.len = msgSize;
|
||||
pMsgSendInfo->msgInfo.handle = trans->transHandle;
|
||||
pMsgSendInfo->msgType = msgType;
|
||||
pMsgSendInfo->fp = fp;
|
||||
|
||||
qDebug("start to send %s msg to node[%d,%s,%d], refId:%" PRIx64 "instance:%p, handle:%p", TMSG_INFO(msgType),
|
||||
ntohl(((SMsgHead *)msg)->vgId), epSet->eps[epSet->inUse].fqdn, epSet->eps[epSet->inUse].port, pJob->refId,
|
||||
|
@ -1744,8 +1778,11 @@ int32_t schAsyncSendMsg(SSchJob *pJob, SSchTask *pTask, void *transport, SEpSet
|
|||
|
||||
_return:
|
||||
|
||||
taosMemoryFreeClear(param);
|
||||
taosMemoryFreeClear(pMsgSendInfo);
|
||||
if (pMsgSendInfo) {
|
||||
taosMemoryFreeClear(pMsgSendInfo->param);
|
||||
taosMemoryFreeClear(pMsgSendInfo);
|
||||
}
|
||||
|
||||
SCH_RET(code);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,21 @@ void taosWLockLatch(SRWLatch *pLatch) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t taosWTryLockLatch(SRWLatch *pLatch) {
|
||||
SRWLatch oLatch, nLatch;
|
||||
oLatch = atomic_load_32(pLatch);
|
||||
if (oLatch) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
nLatch = oLatch | TD_RWLATCH_WRITE_FLAG;
|
||||
if (atomic_val_compare_exchange_32(pLatch, oLatch, nLatch) == oLatch) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void taosWUnLockLatch(SRWLatch *pLatch) { atomic_store_32(pLatch, 0); }
|
||||
|
||||
void taosRLockLatch(SRWLatch *pLatch) {
|
||||
|
|
Loading…
Reference in New Issue