feat: fill physical plan

This commit is contained in:
Xiaoyu Wang 2022-04-30 11:40:12 +08:00
parent 6c178dc0b7
commit 913354057e
15 changed files with 706 additions and 485 deletions

View File

@ -185,6 +185,7 @@ typedef enum ENodeType {
QUERY_NODE_LOGIC_PLAN_VNODE_MODIF, QUERY_NODE_LOGIC_PLAN_VNODE_MODIF,
QUERY_NODE_LOGIC_PLAN_EXCHANGE, QUERY_NODE_LOGIC_PLAN_EXCHANGE,
QUERY_NODE_LOGIC_PLAN_WINDOW, QUERY_NODE_LOGIC_PLAN_WINDOW,
QUERY_NODE_LOGIC_PLAN_FILL,
QUERY_NODE_LOGIC_PLAN_SORT, QUERY_NODE_LOGIC_PLAN_SORT,
QUERY_NODE_LOGIC_PLAN_PARTITION, QUERY_NODE_LOGIC_PLAN_PARTITION,
QUERY_NODE_LOGIC_SUBPLAN, QUERY_NODE_LOGIC_SUBPLAN,
@ -202,6 +203,7 @@ typedef enum ENodeType {
QUERY_NODE_PHYSICAL_PLAN_EXCHANGE, QUERY_NODE_PHYSICAL_PLAN_EXCHANGE,
QUERY_NODE_PHYSICAL_PLAN_SORT, QUERY_NODE_PHYSICAL_PLAN_SORT,
QUERY_NODE_PHYSICAL_PLAN_INTERVAL, QUERY_NODE_PHYSICAL_PLAN_INTERVAL,
QUERY_NODE_PHYSICAL_PLAN_FILL,
QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW, QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW,
QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW, QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW,
QUERY_NODE_PHYSICAL_PLAN_PARTITION, QUERY_NODE_PHYSICAL_PLAN_PARTITION,

View File

@ -102,7 +102,6 @@ typedef struct SWindowLogicNode {
int64_t sliding; int64_t sliding;
int8_t intervalUnit; int8_t intervalUnit;
int8_t slidingUnit; int8_t slidingUnit;
SFillNode* pFill;
int64_t sessionGap; int64_t sessionGap;
SNode* pTspk; SNode* pTspk;
SNode* pStateExpr; SNode* pStateExpr;
@ -110,6 +109,13 @@ typedef struct SWindowLogicNode {
int64_t watermark; int64_t watermark;
} SWindowLogicNode; } SWindowLogicNode;
typedef struct SFillLogicNode {
SLogicNode node;
EFillMode mode;
SNode* pWStartTs;
SNode* pValues; // SNodeListNode
} SFillLogicNode;
typedef struct SSortLogicNode { typedef struct SSortLogicNode {
SLogicNode node; SLogicNode node;
SNodeList* pSortKeys; SNodeList* pSortKeys;
@ -223,10 +229,12 @@ typedef struct SProjectPhysiNode {
typedef struct SJoinPhysiNode { typedef struct SJoinPhysiNode {
SPhysiNode node; SPhysiNode node;
EJoinType joinType; EJoinType joinType;
SNode* pOnConditions; // in or out tuple ? SNode* pOnConditions;
SNodeList* pTargets; SNodeList* pTargets;
} SJoinPhysiNode; } SJoinPhysiNode;
typedef SJoinPhysiNode SSortMergeJoinPhysiNode;
typedef struct SAggPhysiNode { typedef struct SAggPhysiNode {
SPhysiNode node; SPhysiNode node;
SNodeList* pExprs; // these are expression list of group_by_clause and parameter expression of aggregate function SNodeList* pExprs; // these are expression list of group_by_clause and parameter expression of aggregate function
@ -263,9 +271,16 @@ typedef struct SIntervalPhysiNode {
int64_t sliding; int64_t sliding;
int8_t intervalUnit; int8_t intervalUnit;
int8_t slidingUnit; int8_t slidingUnit;
SFillNode* pFill;
} SIntervalPhysiNode; } SIntervalPhysiNode;
typedef struct SFillPhysiNode {
SPhysiNode node;
EFillMode mode;
SNode* pWStartTs; // SColumnNode
SNode* pValues; // SNodeListNode
SNodeList* pTargets;
} SFillPhysiNode;
typedef struct SMultiTableIntervalPhysiNode { typedef struct SMultiTableIntervalPhysiNode {
SIntervalPhysiNode interval; SIntervalPhysiNode interval;
SNodeList* pPartitionKeys; SNodeList* pPartitionKeys;
@ -340,7 +355,7 @@ typedef struct SQueryPlan {
int32_t numOfSubplans; int32_t numOfSubplans;
SNodeList* pSubplans; // Element is SNodeListNode. The execution level of subplan, starting from 0. SNodeList* pSubplans; // Element is SNodeListNode. The execution level of subplan, starting from 0.
SExplainInfo explainInfo; SExplainInfo explainInfo;
SArray* pPlaceholderValues; SArray* pPlaceholderValues;
} SQueryPlan; } SQueryPlan;
void nodesWalkPhysiPlan(SNode* pNode, FNodeWalker walker, void* pContext); void nodesWalkPhysiPlan(SNode* pNode, FNodeWalker walker, void* pContext);

View File

@ -89,7 +89,7 @@ typedef struct SValueNode {
char* p; char* p;
} datum; } datum;
int64_t typeData; int64_t typeData;
char unit; char unit;
} SValueNode; } SValueNode;
typedef struct SOperatorNode { typedef struct SOperatorNode {
@ -211,7 +211,8 @@ typedef enum EFillMode {
typedef struct SFillNode { typedef struct SFillNode {
ENodeType type; // QUERY_NODE_FILL ENodeType type; // QUERY_NODE_FILL
EFillMode mode; EFillMode mode;
SNode* pValues; // SNodeListNode SNode* pValues; // SNodeListNode
SNode* pWStartTs; // _wstartts pseudo column
} SFillNode; } SFillNode;
typedef struct SSelectStmt { typedef struct SSelectStmt {
@ -300,7 +301,7 @@ int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char*
SNodeList** pCols); SNodeList** pCols);
typedef bool (*FFuncClassifier)(int32_t funcId); typedef bool (*FFuncClassifier)(int32_t funcId);
int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNodeList** pFuncs); int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, FFuncClassifier classifier, SNodeList** pFuncs);
int32_t nodesCollectSpecialNodes(SSelectStmt* pSelect, ESqlClause clause, ENodeType type, SNodeList** pNodes); int32_t nodesCollectSpecialNodes(SSelectStmt* pSelect, ESqlClause clause, ENodeType type, SNodeList** pNodes);
@ -314,11 +315,11 @@ bool nodesIsJsonOp(const SOperatorNode* pOp);
bool nodesIsTimeorderQuery(const SNode* pQuery); bool nodesIsTimeorderQuery(const SNode* pQuery);
bool nodesIsTimelineQuery(const SNode* pQuery); bool nodesIsTimelineQuery(const SNode* pQuery);
void* nodesGetValueFromNode(SValueNode* pNode); void* nodesGetValueFromNode(SValueNode* pNode);
int32_t nodesSetValueNodeValue(SValueNode* pNode, void *value); int32_t nodesSetValueNodeValue(SValueNode* pNode, void* value);
char* nodesGetStrValueFromNode(SValueNode* pNode); char* nodesGetStrValueFromNode(SValueNode* pNode);
char* getFillModeString(EFillMode mode); char* getFillModeString(EFillMode mode);
void valueNodeToVariant(const SValueNode* pNode, SVariant* pVal); void valueNodeToVariant(const SValueNode* pNode, SVariant* pVal);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -13,14 +13,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "query.h"
#include "plannodes.h"
#include "commandInt.h" #include "commandInt.h"
#include "plannodes.h"
#include "query.h"
int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pRes); int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplainResNode **pRes);
int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level); int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level);
void qExplainFreeResNode(SExplainResNode *resNode) { void qExplainFreeResNode(SExplainResNode *resNode) {
if (NULL == resNode) { if (NULL == resNode) {
return; return;
@ -28,12 +27,10 @@ void qExplainFreeResNode(SExplainResNode *resNode) {
taosMemoryFreeClear(resNode->pExecInfo); taosMemoryFreeClear(resNode->pExecInfo);
SNode* node = NULL; SNode *node = NULL;
FOREACH(node, resNode->pChildren) { FOREACH(node, resNode->pChildren) { qExplainFreeResNode((SExplainResNode *)node); }
qExplainFreeResNode((SExplainResNode *)node);
}
nodesClearList(resNode->pChildren); nodesClearList(resNode->pChildren);
taosMemoryFreeClear(resNode); taosMemoryFreeClear(resNode);
} }
@ -59,24 +56,24 @@ void qExplainFreeCtx(SExplainCtx *pCtx) {
taosMemoryFreeClear(rsp->subplanInfo); taosMemoryFreeClear(rsp->subplanInfo);
} }
} }
pIter = taosHashIterate(pCtx->groupHash, pIter); pIter = taosHashIterate(pCtx->groupHash, pIter);
} }
} }
taosHashCleanup(pCtx->groupHash); taosHashCleanup(pCtx->groupHash);
taosArrayDestroy(pCtx->rows); taosArrayDestroy(pCtx->rows);
taosMemoryFree(pCtx); taosMemoryFree(pCtx);
} }
int32_t qExplainInitCtx(SExplainCtx **pCtx, SHashObj *groupHash, bool verbose, double ratio, EExplainMode mode) { 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) {
qError("calloc SExplainCtx failed"); qError("calloc SExplainCtx failed");
QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); QRY_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
} }
SArray *rows = taosArrayInit(10, sizeof(SQueryExplainRowInfo)); SArray *rows = taosArrayInit(10, sizeof(SQueryExplainRowInfo));
if (NULL == rows) { if (NULL == rows) {
qError("taosArrayInit SQueryExplainRowInfo failed"); qError("taosArrayInit SQueryExplainRowInfo failed");
@ -95,7 +92,7 @@ int32_t qExplainInitCtx(SExplainCtx **pCtx, SHashObj *groupHash, bool verbose, d
ctx->tbuf = tbuf; ctx->tbuf = tbuf;
ctx->rows = rows; ctx->rows = rows;
ctx->groupHash = groupHash; ctx->groupHash = groupHash;
*pCtx = ctx; *pCtx = ctx;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
@ -110,9 +107,9 @@ _return:
} }
int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNodeList **pChildren) { int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNodeList **pChildren) {
int32_t tlen = 0; int32_t tlen = 0;
SNodeList *pPhysiChildren = NULL; SNodeList *pPhysiChildren = NULL;
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;
@ -120,47 +117,47 @@ int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNo
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;
pPhysiChildren = pTblScanNode->scan.node.pChildren; pPhysiChildren = pTblScanNode->scan.node.pChildren;
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:{ case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: {
SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode; SSystemTableScanPhysiNode *pSTblScanNode = (SSystemTableScanPhysiNode *)pNode;
pPhysiChildren = pSTblScanNode->scan.node.pChildren; pPhysiChildren = pSTblScanNode->scan.node.pChildren;
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:{ case QUERY_NODE_PHYSICAL_PLAN_PROJECT: {
SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode; SProjectPhysiNode *pPrjNode = (SProjectPhysiNode *)pNode;
pPhysiChildren = pPrjNode->node.pChildren; pPhysiChildren = pPrjNode->node.pChildren;
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_JOIN:{ case QUERY_NODE_PHYSICAL_PLAN_JOIN: {
SJoinPhysiNode *pJoinNode = (SJoinPhysiNode *)pNode; SJoinPhysiNode *pJoinNode = (SJoinPhysiNode *)pNode;
pPhysiChildren = pJoinNode->node.pChildren; pPhysiChildren = pJoinNode->node.pChildren;
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_AGG:{ case QUERY_NODE_PHYSICAL_PLAN_AGG: {
SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode; SAggPhysiNode *pAggNode = (SAggPhysiNode *)pNode;
pPhysiChildren = pAggNode->node.pChildren; pPhysiChildren = pAggNode->node.pChildren;
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:{ case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE: {
SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode; SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode;
pPhysiChildren = pExchNode->node.pChildren; pPhysiChildren = pExchNode->node.pChildren;
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_SORT:{ case QUERY_NODE_PHYSICAL_PLAN_SORT: {
SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode; SSortPhysiNode *pSortNode = (SSortPhysiNode *)pNode;
pPhysiChildren = pSortNode->node.pChildren; pPhysiChildren = pSortNode->node.pChildren;
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:{ case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: {
SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode; SIntervalPhysiNode *pIntNode = (SIntervalPhysiNode *)pNode;
pPhysiChildren = pIntNode->window.node.pChildren; pPhysiChildren = pIntNode->window.node.pChildren;
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:{ case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW: {
SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode; SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
pPhysiChildren = pSessNode->window.node.pChildren; pPhysiChildren = pSessNode->window.node.pChildren;
break; break;
@ -178,7 +175,7 @@ int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNo
} }
} }
SNode* node = NULL; SNode *node = NULL;
SExplainResNode *pResNode = NULL; SExplainResNode *pResNode = NULL;
FOREACH(node, pPhysiChildren) { FOREACH(node, pPhysiChildren) {
QRY_ERR_RET(qExplainGenerateResNode((SPhysiNode *)node, group, &pResNode)); QRY_ERR_RET(qExplainGenerateResNode((SPhysiNode *)node, group, &pResNode));
@ -195,14 +192,14 @@ int32_t qExplainGenerateResNodeExecInfo(SArray **pExecInfo, SExplainGroup *group
return TSDB_CODE_QRY_OUT_OF_MEMORY; return TSDB_CODE_QRY_OUT_OF_MEMORY;
} }
SExplainRsp *rsp = NULL; SExplainRsp *rsp = NULL;
for (int32_t i = 0; i < group->nodeNum; ++i) { for (int32_t i = 0; i < group->nodeNum; ++i) {
rsp = taosArrayGet(group->nodeExecInfo, i); rsp = taosArrayGet(group->nodeExecInfo, i);
if (group->physiPlanExecIdx >= rsp->numOfPlans) { if (group->physiPlanExecIdx >= rsp->numOfPlans) {
qError("physiPlanIdx %d exceed plan num %d", group->physiPlanExecIdx, rsp->numOfPlans); qError("physiPlanIdx %d exceed plan num %d", group->physiPlanExecIdx, rsp->numOfPlans);
return TSDB_CODE_QRY_APP_ERROR; return TSDB_CODE_QRY_APP_ERROR;
} }
taosArrayPush(*pExecInfo, rsp->subplanInfo + group->physiPlanExecIdx); taosArrayPush(*pExecInfo, rsp->subplanInfo + group->physiPlanExecIdx);
} }
@ -217,7 +214,7 @@ int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplai
qError("physical node is NULL"); qError("physical node is NULL");
return TSDB_CODE_QRY_APP_ERROR; return TSDB_CODE_QRY_APP_ERROR;
} }
SExplainResNode *resNode = taosMemoryCalloc(1, sizeof(SExplainResNode)); SExplainResNode *resNode = taosMemoryCalloc(1, sizeof(SExplainResNode));
if (NULL == resNode) { if (NULL == resNode) {
qError("calloc SPhysiNodeExplainRes failed"); qError("calloc SPhysiNodeExplainRes failed");
@ -226,15 +223,15 @@ int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplai
int32_t code = 0; int32_t code = 0;
resNode->pNode = pNode; resNode->pNode = pNode;
if (group->nodeExecInfo) { if (group->nodeExecInfo) {
QRY_ERR_JRET(qExplainGenerateResNodeExecInfo(&resNode->pExecInfo, group)); QRY_ERR_JRET(qExplainGenerateResNodeExecInfo(&resNode->pExecInfo, group));
} }
QRY_ERR_JRET(qExplainGenerateResChildren(pNode, group, &resNode->pChildren)); QRY_ERR_JRET(qExplainGenerateResChildren(pNode, group, &resNode->pChildren));
++group->physiPlanNum; ++group->physiPlanNum;
*pResNode = resNode; *pResNode = resNode;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
@ -242,15 +239,15 @@ int32_t qExplainGenerateResNode(SPhysiNode *pNode, SExplainGroup *group, SExplai
_return: _return:
qExplainFreeResNode(resNode); qExplainFreeResNode(resNode);
QRY_RET(code); QRY_RET(code);
} }
int32_t qExplainBufAppendExecInfo(SArray *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); int32_t nodeNum = taosArrayGetSize(pExecInfo);
SExplainExecInfo maxExecInfo = {0}; SExplainExecInfo maxExecInfo = {0};
for (int32_t i = 0; i < nodeNum; ++i) { for (int32_t i = 0; i < nodeNum; ++i) {
SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i); SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i);
if (execInfo->startupCost > maxExecInfo.startupCost) { if (execInfo->startupCost > maxExecInfo.startupCost) {
@ -263,20 +260,20 @@ int32_t qExplainBufAppendExecInfo(SArray *pExecInfo, char *tbuf, int32_t *len) {
maxExecInfo.numOfRows = execInfo->numOfRows; maxExecInfo.numOfRows = execInfo->numOfRows;
} }
} }
EXPLAIN_ROW_APPEND(EXPLAIN_EXECINFO_FORMAT, maxExecInfo.startupCost, maxExecInfo.totalCost, maxExecInfo.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 qExplainBufAppendVerboseExecInfo(SArray *pExecInfo, char *tbuf, int32_t *len) {
int32_t tlen = 0; int32_t tlen = 0;
bool gotVerbose = false; bool gotVerbose = false;
int32_t nodeNum = taosArrayGetSize(pExecInfo); int32_t nodeNum = taosArrayGetSize(pExecInfo);
SExplainExecInfo maxExecInfo = {0}; SExplainExecInfo maxExecInfo = {0};
for (int32_t i = 0; i < nodeNum; ++i) { for (int32_t i = 0; i < nodeNum; ++i) {
SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i); SExplainExecInfo *execInfo = taosArrayGet(pExecInfo, i);
if (execInfo->verboseInfo) { if (execInfo->verboseInfo) {
@ -289,11 +286,10 @@ int32_t qExplainBufAppendVerboseExecInfo(SArray *pExecInfo, char *tbuf, int32_t
} }
*len = tlen; *len = tlen;
return TSDB_CODE_SUCCESS; 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);
@ -304,7 +300,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->dataSize += row.len; ctx->dataSize += row.len;
if (NULL == taosArrayPush(ctx->rows, &row)) { if (NULL == taosArrayPush(ctx->rows, &row)) {
@ -316,21 +312,21 @@ int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static uint8_t getIntervalPrecision(SIntervalPhysiNode* pIntNode) { static uint8_t getIntervalPrecision(SIntervalPhysiNode *pIntNode) {
return ((SColumnNode*)pIntNode->window.pTspk)->node.resType.precision; return ((SColumnNode *)pIntNode->window.pTspk)->node.resType.precision;
} }
int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) { int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) {
int32_t tlen = 0; int32_t tlen = 0;
bool isVerboseLine = false; bool isVerboseLine = false;
char *tbuf = ctx->tbuf; char *tbuf = ctx->tbuf;
bool verbose = ctx->verbose; bool verbose = ctx->verbose;
SPhysiNode* pNode = pResNode->pNode; SPhysiNode *pNode = pResNode->pNode;
if (NULL == pNode) { if (NULL == pNode) {
qError("pyhsical node in explain res node is NULL"); qError("pyhsical node in explain res node is NULL");
return TSDB_CODE_QRY_APP_ERROR; return TSDB_CODE_QRY_APP_ERROR;
} }
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;
@ -339,7 +335,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
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_BLANK_FORMAT);
} }
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTagScanNode->pScanCols->length); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTagScanNode->pScanCols->length);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->totalRowSize);
@ -350,80 +346,85 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
if (verbose) { if (verbose) {
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT); EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pTagScanNode->node.pOutputDataBlockDesc->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
nodesGetOutputNumFromSlotList(pTagScanNode->node.pOutputDataBlockDesc->pSlots));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->outputRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTagScanNode->node.pOutputDataBlockDesc->outputRowSize);
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) { if (pResNode->pExecInfo) {
QRY_ERR_RET(qExplainBufAppendVerboseExecInfo(pResNode->pExecInfo, tbuf, &tlen)); QRY_ERR_RET(qExplainBufAppendVerboseExecInfo(pResNode->pExecInfo, tbuf, &tlen));
if (tlen) { if (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));
} }
} }
} }
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); EXPLAIN_ROW_NEW(level, EXPLAIN_TBL_SCAN_FORMAT, pTblScanNode->scan.tableName.tname);
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_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_BLANK_FORMAT);
} }
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTblScanNode->scan.pScanCols->length); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pTblScanNode->scan.pScanCols->length);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_TABLE_SCAN_FORMAT, pTblScanNode->scanSeq[0], pTblScanNode->scanSeq[1]); EXPLAIN_ROW_APPEND(EXPLAIN_TABLE_SCAN_FORMAT, pTblScanNode->scanSeq[0], pTblScanNode->scanSeq[1]);
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_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_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pTblScanNode->scan.node.pOutputDataBlockDesc->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
nodesGetOutputNumFromSlotList(pTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
EXPLAIN_ROW_END(); EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pTblScanNode->scanRange.skey, pTblScanNode->scanRange.ekey); EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIMERANGE_FORMAT, pTblScanNode->scanRange.skey,
pTblScanNode->scanRange.ekey);
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 (pTblScanNode->scan.node.pConditions) { if (pTblScanNode->scan.node.pConditions) {
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT); EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
QRY_ERR_RET(nodesNodeToSQL(pTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); QRY_ERR_RET(nodesNodeToSQL(pTblScanNode->scan.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));
} }
} }
break; break;
} }
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); EXPLAIN_ROW_NEW(level, EXPLAIN_SYSTBL_SCAN_FORMAT, pSTblScanNode->scan.tableName.tname);
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_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_BLANK_FORMAT);
} }
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSTblScanNode->scan.pScanCols->length); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSTblScanNode->scan.pScanCols->length);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_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_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pSTblScanNode->scan.node.pOutputDataBlockDesc->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
nodesGetOutputNumFromSlotList(pSTblScanNode->scan.node.pOutputDataBlockDesc->pSlots));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSTblScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
EXPLAIN_ROW_END(); EXPLAIN_ROW_END();
@ -431,91 +432,96 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
if (pSTblScanNode->scan.node.pConditions) { if (pSTblScanNode->scan.node.pConditions) {
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT); EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
QRY_ERR_RET(nodesNodeToSQL(pSTblScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); QRY_ERR_RET(nodesNodeToSQL(pSTblScanNode->scan.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));
} }
} }
break; break;
} }
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); EXPLAIN_ROW_NEW(level, EXPLAIN_PROJECTION_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_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_BLANK_FORMAT);
} }
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pPrjNode->pProjections->length); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pPrjNode->pProjections->length);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->totalRowSize);
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_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_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pPrjNode->node.pOutputDataBlockDesc->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
nodesGetOutputNumFromSlotList(pPrjNode->node.pOutputDataBlockDesc->pSlots));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->outputRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pPrjNode->node.pOutputDataBlockDesc->outputRowSize);
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 (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));
EXPLAIN_ROW_END(); EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
} }
} }
break; break;
} }
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)); EXPLAIN_ROW_NEW(level, EXPLAIN_JOIN_FORMAT, EXPLAIN_JOIN_STRING(pJoinNode->joinType));
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_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_BLANK_FORMAT);
} }
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pJoinNode->pTargets->length);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->totalRowSize);
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_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_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
nodesGetOutputNumFromSlotList(pJoinNode->node.pOutputDataBlockDesc->pSlots));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pJoinNode->node.pOutputDataBlockDesc->outputRowSize);
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 (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));
EXPLAIN_ROW_END(); EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
} }
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT); EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
QRY_ERR_RET(nodesNodeToSQL(pJoinNode->pOnConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); QRY_ERR_RET(
nodesNodeToSQL(pJoinNode->pOnConditions, 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));
} }
break; break;
} }
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); EXPLAIN_ROW_NEW(level, EXPLAIN_AGG_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_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_BLANK_FORMAT);
} }
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pAggNode->pAggFuncs->length); EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pAggNode->pAggFuncs->length);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->totalRowSize);
@ -523,57 +529,61 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_GROUPS_FORMAT, pAggNode->pGroupKeys->length); EXPLAIN_ROW_APPEND(EXPLAIN_GROUPS_FORMAT, pAggNode->pGroupKeys->length);
} }
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_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_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pAggNode->node.pOutputDataBlockDesc->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
nodesGetOutputNumFromSlotList(pAggNode->node.pOutputDataBlockDesc->pSlots));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->outputRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pAggNode->node.pOutputDataBlockDesc->outputRowSize);
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 (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));
EXPLAIN_ROW_END(); EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
} }
} }
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE:{ case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE: {
SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode; SExchangePhysiNode *pExchNode = (SExchangePhysiNode *)pNode;
SExplainGroup *group = taosHashGet(ctx->groupHash, &pExchNode->srcGroupId, sizeof(pExchNode->srcGroupId)); SExplainGroup *group = taosHashGet(ctx->groupHash, &pExchNode->srcGroupId, sizeof(pExchNode->srcGroupId));
if (NULL == group) { if (NULL == group) {
qError("exchange src group %d not in groupHash", pExchNode->srcGroupId); qError("exchange src group %d not in groupHash", pExchNode->srcGroupId);
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); EXPLAIN_ROW_NEW(level, EXPLAIN_EXCHANGE_FORMAT, group->nodeNum);
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_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_BLANK_FORMAT);
} }
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->totalRowSize);
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_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_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pExchNode->node.pOutputDataBlockDesc->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
nodesGetOutputNumFromSlotList(pExchNode->node.pOutputDataBlockDesc->pSlots));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->outputRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pExchNode->node.pOutputDataBlockDesc->outputRowSize);
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 (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));
EXPLAIN_ROW_END(); EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
} }
@ -582,14 +592,14 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
QRY_ERR_RET(qExplainAppendGroupResRows(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); EXPLAIN_ROW_NEW(level, EXPLAIN_SORT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_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_BLANK_FORMAT);
} }
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSortNode->pSortKeys->length); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pSortNode->pSortKeys->length);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->totalRowSize);
@ -599,29 +609,31 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
if (verbose) { if (verbose) {
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT); EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
nodesGetOutputNumFromSlotList(pSortNode->node.pOutputDataBlockDesc->pSlots));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSortNode->node.pOutputDataBlockDesc->outputRowSize);
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 (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));
EXPLAIN_ROW_END(); EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
} }
} }
break; break;
} }
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, nodesGetNameFromColumnNode(pIntNode->window.pTspk)); EXPLAIN_ROW_NEW(level, EXPLAIN_INTERVAL_FORMAT, nodesGetNameFromColumnNode(pIntNode->window.pTspk));
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_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_BLANK_FORMAT);
} }
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length); EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pIntNode->window.pFuncs->length);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->totalRowSize);
@ -630,41 +642,39 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
if (verbose) { if (verbose) {
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT); EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
nodesGetOutputNumFromSlotList(pIntNode->window.node.pOutputDataBlockDesc->pSlots));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
EXPLAIN_ROW_END(); EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
uint8_t precision = getIntervalPrecision(pIntNode); uint8_t precision = getIntervalPrecision(pIntNode);
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT, INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision), EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT,
pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision), INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision),
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision), pIntNode->slidingUnit); pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision),
pIntNode->slidingUnit);
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 (pIntNode->pFill) {
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILL_FORMAT, getFillModeString(pIntNode->pFill->mode));
EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
}
if (pIntNode->window.node.pConditions) { if (pIntNode->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(pIntNode->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));
} }
} }
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:{ case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW: {
SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode; SSessionWinodwPhysiNode *pSessNode = (SSessionWinodwPhysiNode *)pNode;
EXPLAIN_ROW_NEW(level, EXPLAIN_SESSION_FORMAT); EXPLAIN_ROW_NEW(level, EXPLAIN_SESSION_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_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_BLANK_FORMAT);
} }
EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pSessNode->window.pFuncs->length); EXPLAIN_ROW_APPEND(EXPLAIN_FUNCTIONS_FORMAT, pSessNode->window.pFuncs->length);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->totalRowSize);
@ -672,10 +682,10 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
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_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, nodesGetOutputNumFromSlotList(pSessNode->window.node.pOutputDataBlockDesc->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
nodesGetOutputNumFromSlotList(pSessNode->window.node.pOutputDataBlockDesc->pSlots));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->outputRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pSessNode->window.node.pOutputDataBlockDesc->outputRowSize);
EXPLAIN_ROW_END(); EXPLAIN_ROW_END();
@ -686,8 +696,9 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
if (pSessNode->window.node.pConditions) { 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(pSessNode->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));
} }
@ -702,7 +713,6 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t qExplainResNodeToRows(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) { int32_t qExplainResNodeToRows(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) {
if (NULL == pResNode) { if (NULL == pResNode) {
qError("explain res node is NULL"); qError("explain res node is NULL");
@ -712,29 +722,28 @@ int32_t qExplainResNodeToRows(SExplainResNode *pResNode, SExplainCtx *ctx, int32
int32_t code = 0; int32_t code = 0;
QRY_ERR_RET(qExplainResNodeToRowsImpl(pResNode, ctx, level)); QRY_ERR_RET(qExplainResNodeToRowsImpl(pResNode, ctx, level));
SNode* pNode = NULL; SNode *pNode = NULL;
FOREACH(pNode, pResNode->pChildren) { FOREACH(pNode, pResNode->pChildren) { QRY_ERR_RET(qExplainResNodeToRows((SExplainResNode *)pNode, ctx, level + 1)); }
QRY_ERR_RET(qExplainResNodeToRows((SExplainResNode *)pNode, ctx, level + 1));
}
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t qExplainAppendGroupResRows(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;
SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId)); SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId));
if (NULL == group) { if (NULL == group) {
qError("group %d not in groupHash", groupId); qError("group %d not in groupHash", groupId);
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR); QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
} }
QRY_ERR_RET(qExplainGenerateResNode(group->plan->pNode, group, &node)); QRY_ERR_RET(qExplainGenerateResNode(group->plan->pNode, group, &node));
if ((EXPLAIN_MODE_ANALYZE == ctx->mode) && (group->physiPlanNum != group->physiPlanExecNum)) { 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); 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(TSDB_CODE_QRY_APP_ERROR);
} }
@ -743,21 +752,21 @@ int32_t qExplainAppendGroupResRows(void *pCtx, int32_t groupId, int32_t level) {
_return: _return:
qExplainFreeResNode(node); qExplainFreeResNode(node);
QRY_RET(code); QRY_RET(code);
} }
int32_t qExplainGetRspFromCtx(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) {
qError("empty explain res rows"); qError("empty explain res rows");
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR); QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
} }
int32_t colNum = 1; int32_t colNum = 1;
int32_t rspSize = sizeof(SRetrieveTableRsp) + sizeof(int32_t) + sizeof(uint64_t) + sizeof(int32_t) * colNum + sizeof(int32_t) * rowNum + pCtx->dataSize; int32_t rspSize = sizeof(SRetrieveTableRsp) + sizeof(int32_t) + sizeof(uint64_t) + 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);
@ -768,13 +777,14 @@ int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
rsp->numOfRows = htonl(rowNum); rsp->numOfRows = htonl(rowNum);
// payload length // payload length
*(int32_t *)rsp->data = sizeof(int32_t) + sizeof(uint64_t) + sizeof(int32_t) * colNum + sizeof(int32_t) * rowNum + pCtx->dataSize; *(int32_t *)rsp->data =
sizeof(int32_t) + sizeof(uint64_t) + sizeof(int32_t) * colNum + sizeof(int32_t) * rowNum + pCtx->dataSize;
// group id // group id
*(uint64_t*)(rsp->data + sizeof(int32_t)) = 0; *(uint64_t *)(rsp->data + sizeof(int32_t)) = 0;
// column length // column length
int32_t* colLength = (int32_t *)(rsp->data + sizeof(int32_t) + sizeof(uint64_t)); int32_t *colLength = (int32_t *)(rsp->data + sizeof(int32_t) + sizeof(uint64_t));
// varchar column offset segment // varchar column offset segment
int32_t *offset = (int32_t *)((char *)colLength + sizeof(int32_t)); int32_t *offset = (int32_t *)((char *)colLength + sizeof(int32_t));
@ -782,7 +792,7 @@ int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
// varchar data real payload // varchar data real payload
char *data = (char *)(offset + rowNum); char *data = (char *)(offset + rowNum);
char* start = data; char *start = data;
for (int32_t i = 0; i < rowNum; ++i) { for (int32_t i = 0; i < rowNum; ++i) {
SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i); SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
offset[i] = data - start; offset[i] = data - start;
@ -800,11 +810,11 @@ int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
} }
int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) { 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;
SExplainCtx *ctx = NULL; SExplainCtx *ctx = NULL;
if (pDag->numOfSubplans <= 0) { if (pDag->numOfSubplans <= 0) {
qError("invalid subplan num:%d", pDag->numOfSubplans); qError("invalid subplan num:%d", pDag->numOfSubplans);
@ -817,13 +827,15 @@ int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); QRY_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
} }
SHashObj *groupHash = taosHashInit(EXPLAIN_MAX_GROUP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK); SHashObj *groupHash =
taosHashInit(EXPLAIN_MAX_GROUP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
if (NULL == groupHash) { if (NULL == groupHash) {
qError("groupHash %d failed", EXPLAIN_MAX_GROUP_NUM); qError("groupHash %d failed", EXPLAIN_MAX_GROUP_NUM);
QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
} }
QRY_ERR_JRET(qExplainInitCtx(&ctx, groupHash, pDag->explainInfo.verbose, pDag->explainInfo.ratio, pDag->explainInfo.mode)); 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);
@ -850,7 +862,7 @@ int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
SExplainGroup group = {0}; SExplainGroup group = {0};
group.nodeNum = 1; group.nodeNum = 1;
group.plan = plan; 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);
@ -872,7 +884,7 @@ int32_t qExplainPrepareCtx(SQueryPlan *pDag, SExplainCtx **pCtx) {
*pCtx = ctx; *pCtx = ctx;
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
_return: _return:
qExplainFreeCtx(ctx); qExplainFreeCtx(ctx);
@ -886,7 +898,7 @@ int32_t qExplainAppendPlanRows(SExplainCtx *pCtx) {
} }
int32_t tlen = 0; int32_t tlen = 0;
char *tbuf = pCtx->tbuf; char *tbuf = pCtx->tbuf;
EXPLAIN_SUM_ROW_NEW(EXPLAIN_RATIO_TIME_FORMAT, pCtx->ratio); EXPLAIN_SUM_ROW_NEW(EXPLAIN_RATIO_TIME_FORMAT, pCtx->ratio);
EXPLAIN_SUM_ROW_END(); EXPLAIN_SUM_ROW_END();
@ -911,11 +923,11 @@ int32_t qExplainGenerateRsp(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp) { int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, int32_t groupId, SRetrieveTableRsp **pRsp) {
SExplainResNode *node = NULL; SExplainResNode *node = NULL;
int32_t code = 0; int32_t code = 0;
bool groupDone = false; bool groupDone = false;
SExplainCtx *ctx = (SExplainCtx *)pCtx; SExplainCtx *ctx = (SExplainCtx *)pCtx;
SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId)); SExplainGroup *group = taosHashGet(ctx->groupHash, &groupId, sizeof(groupId));
if (NULL == group) { if (NULL == group) {
@ -931,30 +943,32 @@ int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, i
qError("taosArrayInit %d explainExecInfo failed", group->nodeNum); qError("taosArrayInit %d explainExecInfo failed", group->nodeNum);
taosMemoryFreeClear(pRspMsg->subplanInfo); taosMemoryFreeClear(pRspMsg->subplanInfo);
taosWUnLockLatch(&group->lock); taosWUnLockLatch(&group->lock);
QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); QRY_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
} }
group->physiPlanExecNum = pRspMsg->numOfPlans; group->physiPlanExecNum = pRspMsg->numOfPlans;
} else if (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum) { } else if (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum) {
qError("group execInfo already full, size:%d, nodeNum:%d", (int32_t)taosArrayGetSize(group->nodeExecInfo), group->nodeNum); qError("group execInfo already full, size:%d, nodeNum:%d", (int32_t)taosArrayGetSize(group->nodeExecInfo),
group->nodeNum);
taosMemoryFreeClear(pRspMsg->subplanInfo); taosMemoryFreeClear(pRspMsg->subplanInfo);
taosWUnLockLatch(&group->lock); taosWUnLockLatch(&group->lock);
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR); QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
} }
if (group->physiPlanExecNum != pRspMsg->numOfPlans) { if (group->physiPlanExecNum != pRspMsg->numOfPlans) {
qError("physiPlanExecNum %d mismatch with others %d in group %d", pRspMsg->numOfPlans, group->physiPlanExecNum, groupId); qError("physiPlanExecNum %d mismatch with others %d in group %d", pRspMsg->numOfPlans, group->physiPlanExecNum,
groupId);
taosMemoryFreeClear(pRspMsg->subplanInfo); taosMemoryFreeClear(pRspMsg->subplanInfo);
taosWUnLockLatch(&group->lock); taosWUnLockLatch(&group->lock);
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR); QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
} }
taosArrayPush(group->nodeExecInfo, pRspMsg); taosArrayPush(group->nodeExecInfo, pRspMsg);
groupDone = (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum); groupDone = (taosArrayGetSize(group->nodeExecInfo) >= group->nodeNum);
taosWUnLockLatch(&group->lock); taosWUnLockLatch(&group->lock);
if (groupDone && (taosHashGetSize(pCtx->groupHash) == atomic_add_fetch_32(&pCtx->groupDoneNum, 1))) { if (groupDone && (taosHashGetSize(pCtx->groupHash) == atomic_add_fetch_32(&pCtx->groupDoneNum, 1))) {
@ -969,14 +983,13 @@ int32_t qExplainUpdateExecInfo(SExplainCtx *pCtx, SExplainRsp *pRspMsg, i
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) { int32_t qExecStaticExplain(SQueryPlan *pDag, SRetrieveTableRsp **pRsp) {
int32_t code = 0; int32_t code = 0;
SExplainCtx *pCtx = NULL; SExplainCtx *pCtx = NULL;
QRY_ERR_RET(qExplainPrepareCtx(pDag, &pCtx)); QRY_ERR_RET(qExplainPrepareCtx(pDag, &pCtx));
QRY_ERR_JRET(qExplainGenerateRsp(pCtx, pRsp)); QRY_ERR_JRET(qExplainGenerateRsp(pCtx, pRsp));
_return: _return:
qExplainFreeCtx(pCtx); qExplainFreeCtx(pCtx);
QRY_RET(code); QRY_RET(code);
@ -984,7 +997,7 @@ _return:
int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int64_t startTs) { int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int64_t startTs) {
QRY_ERR_RET(qExplainPrepareCtx(pDag, pCtx)); QRY_ERR_RET(qExplainPrepareCtx(pDag, pCtx));
(*pCtx)->reqStartTs = startTs; (*pCtx)->reqStartTs = startTs;
(*pCtx)->jobStartTs = taosGetTimestampUs(); (*pCtx)->jobStartTs = taosGetTimestampUs();
@ -994,7 +1007,7 @@ int32_t qExecExplainBegin(SQueryPlan *pDag, SExplainCtx **pCtx, int64_t startTs)
int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) { int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
int32_t code = 0; int32_t code = 0;
pCtx->jobDoneTs = taosGetTimestampUs(); pCtx->jobDoneTs = taosGetTimestampUs();
atomic_store_8((int8_t *)&pCtx->execDone, true); atomic_store_8((int8_t *)&pCtx->execDone, true);
if (taosHashGetSize(pCtx->groupHash) == atomic_load_32(&pCtx->groupDoneNum)) { if (taosHashGetSize(pCtx->groupHash) == atomic_load_32(&pCtx->groupDoneNum)) {
@ -1006,6 +1019,3 @@ int32_t qExecExplainEnd(SExplainCtx *pCtx, SRetrieveTableRsp **pRsp) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }

View File

@ -1179,7 +1179,7 @@ static void setPseudoOutputColInfo(SSDataBlock* pResult, SqlFunctionCtx* pCtx, S
} }
int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx, int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx,
int32_t numOfOutput, SArray* pPseudoList) { int32_t numOfOutput, SArray* pPseudoList) {
setPseudoOutputColInfo(pResult, pCtx, pPseudoList); setPseudoOutputColInfo(pResult, pCtx, pPseudoList);
pResult->info.groupId = pSrcBlock->info.groupId; pResult->info.groupId = pSrcBlock->info.groupId;
@ -1258,7 +1258,7 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc
SColumnInfoData idata = {.info = pResColData->info, .hasNull = true}; SColumnInfoData idata = {.info = pResColData->info, .hasNull = true};
SScalarParam dest = {.columnData = &idata}; SScalarParam dest = {.columnData = &idata};
int32_t code = scalarCalculate((SNode*)pExpr[k].pExpr->_function.pFunctNode, pBlockList, &dest); int32_t code = scalarCalculate((SNode*)pExpr[k].pExpr->_function.pFunctNode, pBlockList, &dest);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
taosArrayDestroy(pBlockList); taosArrayDestroy(pBlockList);
return code; return code;
@ -3959,9 +3959,8 @@ static SSDataBlock* concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SEx
} }
SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp; SRetrieveTableRsp* pTableRsp = pDataInfo->pRsp;
code = code = setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data,
setSDataBlockFromFetchRsp(pExchangeInfo->pResult, pLoadInfo, pTableRsp->numOfRows, pTableRsp->data, pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
pTableRsp->compLen, pTableRsp->numOfCols, startTs, &pDataInfo->totalRows, NULL);
if (code != 0) { if (code != 0) {
goto _error; goto _error;
} }
@ -4781,8 +4780,8 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
// there is an scalar expression that needs to be calculated before apply the group aggregation. // there is an scalar expression that needs to be calculated before apply the group aggregation.
if (pAggInfo->pScalarExprInfo != NULL) { if (pAggInfo->pScalarExprInfo != NULL) {
int32_t code = projectApplyFunctions(pAggInfo->pScalarExprInfo, pBlock, pBlock, pAggInfo->pScalarCtx, pAggInfo->numOfScalarExpr, int32_t code = projectApplyFunctions(pAggInfo->pScalarExprInfo, pBlock, pBlock, pAggInfo->pScalarCtx,
NULL); pAggInfo->numOfScalarExpr, NULL);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
pTaskInfo->code = code; pTaskInfo->code = code;
longjmp(pTaskInfo->env, pTaskInfo->code); longjmp(pTaskInfo->env, pTaskInfo->code);
@ -6540,8 +6539,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
int32_t numOfCols = 0; int32_t numOfCols = 0;
SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols); SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pScanPhyNode->node.pOutputDataBlockDesc, &numOfCols);
SOperatorInfo* pOperator = SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo,
createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo, pScanPhyNode->node.pConditions); pScanPhyNode->node.pConditions);
taosArrayDestroy(tableIdList); taosArrayDestroy(tableIdList);
return pOperator; return pOperator;
} else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) { } else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
@ -6622,10 +6621,11 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
pOptr = createIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, primaryTsSlotId, &as, pOptr = createIntervalOperatorInfo(ops[0], pExprInfo, num, pResBlock, &interval, primaryTsSlotId, &as,
pTableGroupInfo, pTaskInfo); pTableGroupInfo, pTaskInfo);
if (pIntervalPhyNode->pFill != NULL) { // if (pIntervalPhyNode->pFill != NULL) {
pOptr = createFillOperatorInfo(pOptr, pExprInfo, num, &interval, pResBlock, pIntervalPhyNode->pFill->mode, NULL, // pOptr = createFillOperatorInfo(pOptr, pExprInfo, num, &interval, pResBlock, pIntervalPhyNode->pFill->mode,
false, pTaskInfo); // NULL,
} // false, pTaskInfo);
// }
} else if (QUERY_NODE_PHYSICAL_PLAN_SORT == type) { } else if (QUERY_NODE_PHYSICAL_PLAN_SORT == type) {
SSortPhysiNode* pSortPhyNode = (SSortPhysiNode*)pPhyNode; SSortPhysiNode* pSortPhyNode = (SSortPhysiNode*)pPhyNode;
@ -6927,7 +6927,7 @@ tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle*
code = initQueryTableDataCond(&cond, pTableScanNode); code = initQueryTableDataCond(&cond, pTableScanNode);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
goto _error; goto _error;
} }
#if 0 #if 0
return tsdbQueryTables(pHandle->reader, &cond, pTableGroupInfo, queryId, taskId); return tsdbQueryTables(pHandle->reader, &cond, pTableGroupInfo, queryId, taskId);
#endif #endif

View File

@ -191,6 +191,7 @@ static SNode* nodeListNodeCopy(const SNodeListNode* pSrc, SNodeListNode* pDst) {
static SNode* fillNodeCopy(const SFillNode* pSrc, SFillNode* pDst) { static SNode* fillNodeCopy(const SFillNode* pSrc, SFillNode* pDst) {
COPY_SCALAR_FIELD(mode); COPY_SCALAR_FIELD(mode);
CLONE_NODE_FIELD(pValues); CLONE_NODE_FIELD(pValues);
CLONE_NODE_FIELD(pWStartTs);
return (SNode*)pDst; return (SNode*)pDst;
} }
@ -269,11 +270,18 @@ static SNode* logicWindowCopy(const SWindowLogicNode* pSrc, SWindowLogicNode* pD
COPY_ALL_SCALAR_FIELDS; COPY_ALL_SCALAR_FIELDS;
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy); COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
CLONE_NODE_LIST_FIELD(pFuncs); CLONE_NODE_LIST_FIELD(pFuncs);
CLONE_NODE_FIELD(pFill);
CLONE_NODE_FIELD(pTspk); CLONE_NODE_FIELD(pTspk);
return (SNode*)pDst; return (SNode*)pDst;
} }
static SNode* logicFillCopy(const SFillLogicNode* pSrc, SFillLogicNode* pDst) {
COPY_ALL_SCALAR_FIELDS;
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
CLONE_NODE_FIELD(pWStartTs);
CLONE_NODE_FIELD(pValues);
return (SNode*)pDst;
}
static SNode* logicSortCopy(const SSortLogicNode* pSrc, SSortLogicNode* pDst) { static SNode* logicSortCopy(const SSortLogicNode* pSrc, SSortLogicNode* pDst) {
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy); COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
CLONE_NODE_LIST_FIELD(pSortKeys); CLONE_NODE_LIST_FIELD(pSortKeys);
@ -370,6 +378,8 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) {
return logicExchangeCopy((const SExchangeLogicNode*)pNode, (SExchangeLogicNode*)pDst); return logicExchangeCopy((const SExchangeLogicNode*)pNode, (SExchangeLogicNode*)pDst);
case QUERY_NODE_LOGIC_PLAN_WINDOW: case QUERY_NODE_LOGIC_PLAN_WINDOW:
return logicWindowCopy((const SWindowLogicNode*)pNode, (SWindowLogicNode*)pDst); return logicWindowCopy((const SWindowLogicNode*)pNode, (SWindowLogicNode*)pDst);
case QUERY_NODE_LOGIC_PLAN_FILL:
return logicFillCopy((const SFillLogicNode*)pNode, (SFillLogicNode*)pDst);
case QUERY_NODE_LOGIC_PLAN_SORT: case QUERY_NODE_LOGIC_PLAN_SORT:
return logicSortCopy((const SSortLogicNode*)pNode, (SSortLogicNode*)pDst); return logicSortCopy((const SSortLogicNode*)pNode, (SSortLogicNode*)pDst);
case QUERY_NODE_LOGIC_PLAN_PARTITION: case QUERY_NODE_LOGIC_PLAN_PARTITION:

View File

@ -192,6 +192,8 @@ const char* nodesNodeName(ENodeType type) {
return "LogicExchange"; return "LogicExchange";
case QUERY_NODE_LOGIC_PLAN_WINDOW: case QUERY_NODE_LOGIC_PLAN_WINDOW:
return "LogicWindow"; return "LogicWindow";
case QUERY_NODE_LOGIC_PLAN_FILL:
return "LogicFill";
case QUERY_NODE_LOGIC_PLAN_SORT: case QUERY_NODE_LOGIC_PLAN_SORT:
return "LogicSort"; return "LogicSort";
case QUERY_NODE_LOGIC_PLAN_PARTITION: case QUERY_NODE_LOGIC_PLAN_PARTITION:
@ -222,6 +224,8 @@ const char* nodesNodeName(ENodeType type) {
return "PhysiSort"; return "PhysiSort";
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
return "PhysiInterval"; return "PhysiInterval";
case QUERY_NODE_PHYSICAL_PLAN_FILL:
return "PhysiFill";
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW: case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
return "PhysiSessionWindow"; return "PhysiSessionWindow";
case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW: case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW:
@ -564,6 +568,44 @@ static int32_t jsonToLogicProjectNode(const SJson* pJson, void* pObj) {
return code; return code;
} }
static const char* jkFillLogicPlanMode = "Mode";
static const char* jkFillLogicPlanWStartTs = "WStartTs";
static const char* jkFillLogicPlanValues = "Values";
static int32_t logicFillNodeToJson(const void* pObj, SJson* pJson) {
const SFillLogicNode* pNode = (const SFillLogicNode*)pObj;
int32_t code = logicPlanNodeToJson(pObj, pJson);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkFillLogicPlanMode, pNode->mode);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkFillLogicPlanWStartTs, nodeToJson, pNode->pWStartTs);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkFillLogicPlanValues, nodeToJson, pNode->pValues);
}
return code;
}
static int32_t jsonToLogicFillNode(const SJson* pJson, void* pObj) {
SFillLogicNode* pNode = (SFillLogicNode*)pObj;
int32_t code = jsonToLogicPlanNode(pJson, pObj);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetNumberValue(pJson, jkFillLogicPlanMode, pNode->mode);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkFillLogicPlanWStartTs, &pNode->pWStartTs);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkFillLogicPlanValues, &pNode->pValues);
}
return code;
}
static const char* jkSortLogicPlanSortKeys = "SortKeys"; static const char* jkSortLogicPlanSortKeys = "SortKeys";
static int32_t logicSortNodeToJson(const void* pObj, SJson* pJson) { static int32_t logicSortNodeToJson(const void* pObj, SJson* pJson) {
@ -1382,7 +1424,6 @@ static const char* jkIntervalPhysiPlanOffset = "Offset";
static const char* jkIntervalPhysiPlanSliding = "Sliding"; static const char* jkIntervalPhysiPlanSliding = "Sliding";
static const char* jkIntervalPhysiPlanIntervalUnit = "intervalUnit"; static const char* jkIntervalPhysiPlanIntervalUnit = "intervalUnit";
static const char* jkIntervalPhysiPlanSlidingUnit = "slidingUnit"; static const char* jkIntervalPhysiPlanSlidingUnit = "slidingUnit";
static const char* jkIntervalPhysiPlanFill = "Fill";
static int32_t physiIntervalNodeToJson(const void* pObj, SJson* pJson) { static int32_t physiIntervalNodeToJson(const void* pObj, SJson* pJson) {
const SIntervalPhysiNode* pNode = (const SIntervalPhysiNode*)pObj; const SIntervalPhysiNode* pNode = (const SIntervalPhysiNode*)pObj;
@ -1403,9 +1444,6 @@ static int32_t physiIntervalNodeToJson(const void* pObj, SJson* pJson) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanSlidingUnit, pNode->slidingUnit); code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanSlidingUnit, pNode->slidingUnit);
} }
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkIntervalPhysiPlanFill, nodeToJson, pNode->pFill);
}
return code; return code;
} }
@ -1429,8 +1467,50 @@ static int32_t jsonToPhysiIntervalNode(const SJson* pJson, void* pObj) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetTinyIntValue(pJson, jkIntervalPhysiPlanSlidingUnit, &pNode->slidingUnit); code = tjsonGetTinyIntValue(pJson, jkIntervalPhysiPlanSlidingUnit, &pNode->slidingUnit);
} }
return code;
}
static const char* jkFillPhysiPlanMode = "Mode";
static const char* jkFillPhysiPlanWStartTs = "WStartTs";
static const char* jkFillPhysiPlanValues = "Values";
static const char* jkFillPhysiPlanTargets = "Targets";
static int32_t physiFillNodeToJson(const void* pObj, SJson* pJson) {
const SFillPhysiNode* pNode = (const SFillPhysiNode*)pObj;
int32_t code = physicPlanNodeToJson(pObj, pJson);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkIntervalPhysiPlanFill, (SNode**)&pNode->pFill); code = tjsonAddIntegerToObject(pJson, jkFillPhysiPlanMode, pNode->mode);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkFillPhysiPlanWStartTs, nodeToJson, pNode->pWStartTs);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkFillPhysiPlanValues, nodeToJson, pNode->pValues);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkFillPhysiPlanTargets, pNode->pTargets);
}
return code;
}
static int32_t jsonToPhysiFillNode(const SJson* pJson, void* pObj) {
SFillPhysiNode* pNode = (SFillPhysiNode*)pObj;
int32_t code = jsonToPhysiWindowNode(pJson, pObj);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetNumberValue(pJson, jkFillPhysiPlanMode, pNode->mode);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkFillPhysiPlanWStartTs, &pNode->pWStartTs);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkFillPhysiPlanValues, &pNode->pValues);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkFillPhysiPlanTargets, &pNode->pTargets);
} }
return code; return code;
@ -2328,6 +2408,7 @@ static int32_t jsonToNodeListNode(const SJson* pJson, void* pObj) {
static const char* jkFillMode = "Mode"; static const char* jkFillMode = "Mode";
static const char* jkFillValues = "Values"; static const char* jkFillValues = "Values";
static const char* jkFillWStartTs = "WStartTs";
static int32_t fillNodeToJson(const void* pObj, SJson* pJson) { static int32_t fillNodeToJson(const void* pObj, SJson* pJson) {
const SFillNode* pNode = (const SFillNode*)pObj; const SFillNode* pNode = (const SFillNode*)pObj;
@ -2336,6 +2417,9 @@ static int32_t fillNodeToJson(const void* pObj, SJson* pJson) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkFillValues, nodeToJson, pNode->pValues); code = tjsonAddObject(pJson, jkFillValues, nodeToJson, pNode->pValues);
} }
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkFillWStartTs, nodeToJson, pNode->pWStartTs);
}
return code; return code;
} }
@ -2347,6 +2431,9 @@ static int32_t jsonToFillNode(const SJson* pJson, void* pObj) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkFillValues, &pNode->pValues); code = jsonToNodeObject(pJson, jkFillValues, &pNode->pValues);
} }
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkFillWStartTs, &pNode->pWStartTs);
}
return code; return code;
} }
@ -2707,6 +2794,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return logicProjectNodeToJson(pObj, pJson); return logicProjectNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_VNODE_MODIF: case QUERY_NODE_LOGIC_PLAN_VNODE_MODIF:
break; break;
case QUERY_NODE_LOGIC_PLAN_FILL:
return logicFillNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_SORT: case QUERY_NODE_LOGIC_PLAN_SORT:
return logicSortNodeToJson(pObj, pJson); return logicSortNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_PARTITION: case QUERY_NODE_LOGIC_PLAN_PARTITION:
@ -2735,6 +2824,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return physiSortNodeToJson(pObj, pJson); return physiSortNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
return physiIntervalNodeToJson(pObj, pJson); return physiIntervalNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_FILL:
return physiFillNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW: case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
return physiSessionWindowNodeToJson(pObj, pJson); return physiSessionWindowNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW: case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW:
@ -2795,6 +2886,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToLogicScanNode(pJson, pObj); return jsonToLogicScanNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_PROJECT: case QUERY_NODE_LOGIC_PLAN_PROJECT:
return jsonToLogicProjectNode(pJson, pObj); return jsonToLogicProjectNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_FILL:
return jsonToLogicFillNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_SORT: case QUERY_NODE_LOGIC_PLAN_SORT:
return jsonToLogicSortNode(pJson, pObj); return jsonToLogicSortNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_PARTITION: case QUERY_NODE_LOGIC_PLAN_PARTITION:
@ -2821,6 +2914,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToPhysiSortNode(pJson, pObj); return jsonToPhysiSortNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
return jsonToPhysiIntervalNode(pJson, pObj); return jsonToPhysiIntervalNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_FILL:
return jsonToPhysiFillNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW: case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
return jsonToPhysiSessionWindowNode(pJson, pObj); return jsonToPhysiSessionWindowNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW: case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW:

View File

@ -132,9 +132,14 @@ static EDealRes dispatchExpr(SNode* pNode, ETraversalOrder order, FNodeWalker wa
case QUERY_NODE_NODE_LIST: case QUERY_NODE_NODE_LIST:
res = walkExprs(((SNodeListNode*)pNode)->pNodeList, order, walker, pContext); res = walkExprs(((SNodeListNode*)pNode)->pNodeList, order, walker, pContext);
break; break;
case QUERY_NODE_FILL: case QUERY_NODE_FILL: {
res = walkExpr(((SFillNode*)pNode)->pValues, order, walker, pContext); SFillNode* pFill = (SFillNode*)pNode;
res = walkExpr(pFill->pValues, order, walker, pContext);
if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
res = walkExpr(pFill->pWStartTs, order, walker, pContext);
}
break; break;
}
case QUERY_NODE_RAW_EXPR: case QUERY_NODE_RAW_EXPR:
res = walkExpr(((SRawExprNode*)pNode)->pNode, order, walker, pContext); res = walkExpr(((SRawExprNode*)pNode)->pNode, order, walker, pContext);
break; break;
@ -272,9 +277,14 @@ static EDealRes rewriteExpr(SNode** pRawNode, ETraversalOrder order, FNodeRewrit
case QUERY_NODE_NODE_LIST: case QUERY_NODE_NODE_LIST:
res = rewriteExprs(((SNodeListNode*)pNode)->pNodeList, order, rewriter, pContext); res = rewriteExprs(((SNodeListNode*)pNode)->pNodeList, order, rewriter, pContext);
break; break;
case QUERY_NODE_FILL: case QUERY_NODE_FILL: {
res = rewriteExpr(&(((SFillNode*)pNode)->pValues), order, rewriter, pContext); SFillNode* pFill = (SFillNode*)pNode;
res = rewriteExpr(&pFill->pValues, order, rewriter, pContext);
if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
res = rewriteExpr(&(pFill->pWStartTs), order, rewriter, pContext);
}
break; break;
}
case QUERY_NODE_RAW_EXPR: case QUERY_NODE_RAW_EXPR:
res = rewriteExpr(&(((SRawExprNode*)pNode)->pNode), order, rewriter, pContext); res = rewriteExpr(&(((SRawExprNode*)pNode)->pNode), order, rewriter, pContext);
break; break;
@ -333,6 +343,9 @@ void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker wa
case SQL_CLAUSE_PARTITION_BY: case SQL_CLAUSE_PARTITION_BY:
nodesWalkExpr(pSelect->pWindow, walker, pContext); nodesWalkExpr(pSelect->pWindow, walker, pContext);
case SQL_CLAUSE_WINDOW: case SQL_CLAUSE_WINDOW:
if (NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow)) {
nodesWalkExpr(((SIntervalWindowNode*)pSelect->pWindow)->pFill, walker, pContext);
}
nodesWalkExprs(pSelect->pGroupByList, walker, pContext); nodesWalkExprs(pSelect->pGroupByList, walker, pContext);
case SQL_CLAUSE_GROUP_BY: case SQL_CLAUSE_GROUP_BY:
nodesWalkExpr(pSelect->pHaving, walker, pContext); nodesWalkExpr(pSelect->pHaving, walker, pContext);
@ -362,6 +375,9 @@ void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewrit
case SQL_CLAUSE_PARTITION_BY: case SQL_CLAUSE_PARTITION_BY:
nodesRewriteExpr(&(pSelect->pWindow), rewriter, pContext); nodesRewriteExpr(&(pSelect->pWindow), rewriter, pContext);
case SQL_CLAUSE_WINDOW: case SQL_CLAUSE_WINDOW:
if (NULL != pSelect->pWindow && QUERY_NODE_INTERVAL_WINDOW == nodeType(pSelect->pWindow)) {
nodesRewriteExpr(&(((SIntervalWindowNode*)pSelect->pWindow)->pFill), rewriter, pContext);
}
nodesRewriteExprs(pSelect->pGroupByList, rewriter, pContext); nodesRewriteExprs(pSelect->pGroupByList, rewriter, pContext);
case SQL_CLAUSE_GROUP_BY: case SQL_CLAUSE_GROUP_BY:
nodesRewriteExpr(&(pSelect->pHaving), rewriter, pContext); nodesRewriteExpr(&(pSelect->pHaving), rewriter, pContext);
@ -496,14 +512,9 @@ static EDealRes dispatchPhysiPlan(SNode* pNode, ETraversalOrder order, FNodeWalk
} }
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: { case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
SIntervalPhysiNode* pInterval = (SIntervalPhysiNode*)pNode;
res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext); res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext);
if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
res = walkPhysiPlan((SNode*)pInterval->pFill, order, walker, pContext);
}
break; break;
}
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW: case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext); res = walkWindowPhysi((SWinodwPhysiNode*)pNode, order, walker, pContext);
break; break;

View File

@ -213,6 +213,8 @@ SNodeptr nodesMakeNode(ENodeType type) {
return makeNode(type, sizeof(SExchangeLogicNode)); return makeNode(type, sizeof(SExchangeLogicNode));
case QUERY_NODE_LOGIC_PLAN_WINDOW: case QUERY_NODE_LOGIC_PLAN_WINDOW:
return makeNode(type, sizeof(SWindowLogicNode)); return makeNode(type, sizeof(SWindowLogicNode));
case QUERY_NODE_LOGIC_PLAN_FILL:
return makeNode(type, sizeof(SFillLogicNode));
case QUERY_NODE_LOGIC_PLAN_SORT: case QUERY_NODE_LOGIC_PLAN_SORT:
return makeNode(type, sizeof(SSortLogicNode)); return makeNode(type, sizeof(SSortLogicNode));
case QUERY_NODE_LOGIC_PLAN_PARTITION: case QUERY_NODE_LOGIC_PLAN_PARTITION:
@ -243,6 +245,8 @@ SNodeptr nodesMakeNode(ENodeType type) {
return makeNode(type, sizeof(SSortPhysiNode)); return makeNode(type, sizeof(SSortPhysiNode));
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
return makeNode(type, sizeof(SIntervalPhysiNode)); return makeNode(type, sizeof(SIntervalPhysiNode));
case QUERY_NODE_PHYSICAL_PLAN_FILL:
return makeNode(type, sizeof(SFillPhysiNode));
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW: case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
return makeNode(type, sizeof(SSessionWinodwPhysiNode)); return makeNode(type, sizeof(SSessionWinodwPhysiNode));
case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW: case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW:
@ -373,9 +377,12 @@ void nodesDestroyNode(SNodeptr pNode) {
case QUERY_NODE_NODE_LIST: case QUERY_NODE_NODE_LIST:
nodesDestroyList(((SNodeListNode*)pNode)->pNodeList); nodesDestroyList(((SNodeListNode*)pNode)->pNodeList);
break; break;
case QUERY_NODE_FILL: case QUERY_NODE_FILL: {
nodesDestroyNode(((SFillNode*)pNode)->pValues); SFillNode* pFill = (SFillNode*)pNode;
nodesDestroyNode(pFill->pValues);
nodesDestroyNode(pFill->pWStartTs);
break; break;
}
case QUERY_NODE_RAW_EXPR: case QUERY_NODE_RAW_EXPR:
nodesDestroyNode(((SRawExprNode*)pNode)->pNode); nodesDestroyNode(((SRawExprNode*)pNode)->pNode);
break; break;
@ -554,7 +561,6 @@ void nodesDestroyNode(SNodeptr pNode) {
SWindowLogicNode* pLogicNode = (SWindowLogicNode*)pNode; SWindowLogicNode* pLogicNode = (SWindowLogicNode*)pNode;
destroyLogicNode((SLogicNode*)pLogicNode); destroyLogicNode((SLogicNode*)pLogicNode);
nodesDestroyList(pLogicNode->pFuncs); nodesDestroyList(pLogicNode->pFuncs);
nodesDestroyNode(pLogicNode->pFill);
nodesDestroyNode(pLogicNode->pTspk); nodesDestroyNode(pLogicNode->pTspk);
break; break;
} }
@ -630,12 +636,9 @@ void nodesDestroyNode(SNodeptr pNode) {
nodesDestroyNode(pPhyNode->pSortKeys); nodesDestroyNode(pPhyNode->pSortKeys);
break; break;
} }
case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: { case QUERY_NODE_PHYSICAL_PLAN_INTERVAL:
SIntervalPhysiNode* pPhyNode = (SIntervalPhysiNode*)pNode; destroyWinodwPhysiNode((SWinodwPhysiNode*)pNode);
destroyWinodwPhysiNode((SWinodwPhysiNode*)pPhyNode);
nodesDestroyNode(pPhyNode->pFill);
break; break;
}
case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW: case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW:
destroyWinodwPhysiNode((SWinodwPhysiNode*)pNode); destroyWinodwPhysiNode((SWinodwPhysiNode*)pNode);
break; break;
@ -894,7 +897,7 @@ void* nodesGetValueFromNode(SValueNode* pNode) {
return NULL; return NULL;
} }
int32_t nodesSetValueNodeValue(SValueNode* pNode, void *value) { int32_t nodesSetValueNodeValue(SValueNode* pNode, void* value) {
switch (pNode->node.resType.type) { switch (pNode->node.resType.type) {
case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_BOOL:
pNode->datum.b = *(bool*)value; pNode->datum.b = *(bool*)value;
@ -1192,7 +1195,7 @@ static EDealRes collectFuncs(SNode* pNode, void* pContext) {
return DEAL_RES_CONTINUE; return DEAL_RES_CONTINUE;
} }
int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNodeList** pFuncs) { int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, FFuncClassifier classifier, SNodeList** pFuncs) {
if (NULL == pSelect || NULL == pFuncs) { if (NULL == pSelect || NULL == pFuncs) {
return TSDB_CODE_FAILED; return TSDB_CODE_FAILED;
} }
@ -1203,7 +1206,7 @@ int32_t nodesCollectFuncs(SSelectStmt* pSelect, FFuncClassifier classifier, SNod
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
*pFuncs = NULL; *pFuncs = NULL;
nodesWalkSelectStmt(pSelect, SQL_CLAUSE_GROUP_BY, collectFuncs, &cxt); nodesWalkSelectStmt(pSelect, clause, collectFuncs, &cxt);
if (TSDB_CODE_SUCCESS != cxt.errCode) { if (TSDB_CODE_SUCCESS != cxt.errCode) {
nodesDestroyList(cxt.pFuncs); nodesDestroyList(cxt.pFuncs);
return cxt.errCode; return cxt.errCode;

View File

@ -501,6 +501,12 @@ SNode* createFillNode(SAstCreateContext* pCxt, EFillMode mode, SNode* pValues) {
CHECK_OUT_OF_MEM(fill); CHECK_OUT_OF_MEM(fill);
fill->mode = mode; fill->mode = mode;
fill->pValues = pValues; fill->pValues = pValues;
fill->pWStartTs = nodesMakeNode(QUERY_NODE_FUNCTION);
if (NULL == fill->pWStartTs) {
nodesDestroyNode(fill);
CHECK_OUT_OF_MEM(fill->pWStartTs);
}
strcpy(((SFunctionNode*)fill->pWStartTs)->functionName, "_wstartts");
return (SNode*)fill; return (SNode*)fill;
} }

View File

@ -26,193 +26,192 @@ typedef struct SKeyword {
uint8_t len; // length uint8_t len; // length
} SKeyword; } SKeyword;
// clang-format off
// keywords in sql string // keywords in sql string
static SKeyword keywordTable[] = { static SKeyword keywordTable[] = {
{"ACCOUNT", TK_ACCOUNT}, {"ACCOUNT", TK_ACCOUNT},
{"ACCOUNTS", TK_ACCOUNTS}, {"ACCOUNTS", TK_ACCOUNTS},
{"ADD", TK_ADD}, {"ADD", TK_ADD},
{"AGGREGATE", TK_AGGREGATE}, {"AGGREGATE", TK_AGGREGATE},
{"ALL", TK_ALL}, {"ALL", TK_ALL},
{"ALTER", TK_ALTER}, {"ALTER", TK_ALTER},
{"ANALYZE", TK_ANALYZE}, {"ANALYZE", TK_ANALYZE},
{"AND", TK_AND}, {"AND", TK_AND},
{"APPS", TK_APPS}, {"APPS", TK_APPS},
{"AS", TK_AS}, {"AS", TK_AS},
{"ASC", TK_ASC}, {"ASC", TK_ASC},
{"AT_ONCE", TK_AT_ONCE}, {"AT_ONCE", TK_AT_ONCE},
{"BETWEEN", TK_BETWEEN}, {"BETWEEN", TK_BETWEEN},
{"BINARY", TK_BINARY}, {"BINARY", TK_BINARY},
{"BIGINT", TK_BIGINT}, {"BIGINT", TK_BIGINT},
// {"BLOCKS", TK_BLOCKS}, {"BNODE", TK_BNODE},
{"BNODE", TK_BNODE}, {"BNODES", TK_BNODES},
{"BNODES", TK_BNODES}, {"BOOL", TK_BOOL},
{"BOOL", TK_BOOL}, {"BUFFER", TK_BUFFER},
{"BUFFER", TK_BUFFER}, {"BUFSIZE", TK_BUFSIZE},
{"BUFSIZE", TK_BUFSIZE}, {"BY", TK_BY},
{"BY", TK_BY}, {"CACHE", TK_CACHE},
{"CACHE", TK_CACHE}, {"CACHELAST", TK_CACHELAST},
{"CACHELAST", TK_CACHELAST}, {"CAST", TK_CAST},
{"CAST", TK_CAST}, {"CLUSTER", TK_CLUSTER},
{"CLUSTER", TK_CLUSTER}, {"COLUMN", TK_COLUMN},
{"COLUMN", TK_COLUMN}, {"COMMENT", TK_COMMENT},
{"COMMENT", TK_COMMENT}, {"COMP", TK_COMP},
{"COMP", TK_COMP}, {"COMPACT", TK_COMPACT},
{"COMPACT", TK_COMPACT}, {"CONNS", TK_CONNS},
{"CONNS", TK_CONNS}, {"CONNECTION", TK_CONNECTION},
{"CONNECTION", TK_CONNECTION}, {"CONNECTIONS", TK_CONNECTIONS},
{"CONNECTIONS", TK_CONNECTIONS}, {"COUNT", TK_COUNT},
{"COUNT", TK_COUNT}, {"CREATE", TK_CREATE},
{"CREATE", TK_CREATE}, {"DATABASE", TK_DATABASE},
{"DATABASE", TK_DATABASE}, {"DATABASES", TK_DATABASES},
{"DATABASES", TK_DATABASES}, {"DAYS", TK_DAYS},
{"DAYS", TK_DAYS}, {"DBS", TK_DBS},
{"DBS", TK_DBS}, {"DELAY", TK_DELAY},
{"DELAY", TK_DELAY}, {"DESC", TK_DESC},
{"DESC", TK_DESC}, {"DESCRIBE", TK_DESCRIBE},
{"DESCRIBE", TK_DESCRIBE}, {"DISTINCT", TK_DISTINCT},
{"DISTINCT", TK_DISTINCT}, {"DNODE", TK_DNODE},
{"DNODE", TK_DNODE}, {"DNODES", TK_DNODES},
{"DNODES", TK_DNODES}, {"DOUBLE", TK_DOUBLE},
{"DOUBLE", TK_DOUBLE}, {"DROP", TK_DROP},
{"DROP", TK_DROP}, {"EXISTS", TK_EXISTS},
{"EXISTS", TK_EXISTS}, {"EXPLAIN", TK_EXPLAIN},
{"EXPLAIN", TK_EXPLAIN}, {"FILE_FACTOR", TK_FILE_FACTOR},
{"FILE_FACTOR", TK_FILE_FACTOR}, {"FILL", TK_FILL},
{"FILL", TK_FILL}, {"FIRST", TK_FIRST},
{"FIRST", TK_FIRST}, {"FLOAT", TK_FLOAT},
{"FLOAT", TK_FLOAT}, {"FROM", TK_FROM},
{"FROM", TK_FROM}, {"FSYNC", TK_FSYNC},
{"FSYNC", TK_FSYNC}, {"FUNCTION", TK_FUNCTION},
{"FUNCTION", TK_FUNCTION}, {"FUNCTIONS", TK_FUNCTIONS},
{"FUNCTIONS", TK_FUNCTIONS}, {"GRANTS", TK_GRANTS},
{"GRANTS", TK_GRANTS}, {"GROUP", TK_GROUP},
{"GROUP", TK_GROUP}, {"HAVING", TK_HAVING},
{"HAVING", TK_HAVING}, {"IF", TK_IF},
{"IF", TK_IF}, {"IMPORT", TK_IMPORT},
{"IMPORT", TK_IMPORT}, {"IN", TK_IN},
{"IN", TK_IN}, {"INDEX", TK_INDEX},
{"INDEX", TK_INDEX}, {"INDEXES", TK_INDEXES},
{"INDEXES", TK_INDEXES}, {"INNER", TK_INNER},
{"INNER", TK_INNER}, {"INT", TK_INT},
{"INT", TK_INT}, {"INSERT", TK_INSERT},
{"INSERT", TK_INSERT}, {"INTEGER", TK_INTEGER},
{"INTEGER", TK_INTEGER}, {"INTERVAL", TK_INTERVAL},
{"INTERVAL", TK_INTERVAL}, {"INTO", TK_INTO},
{"INTO", TK_INTO}, {"IS", TK_IS},
{"IS", TK_IS}, {"JOIN", TK_JOIN},
{"JOIN", TK_JOIN}, {"JSON", TK_JSON},
{"JSON", TK_JSON}, {"KEEP", TK_KEEP},
{"KEEP", TK_KEEP}, {"KILL", TK_KILL},
{"KILL", TK_KILL}, {"LAST", TK_LAST},
{"LAST", TK_LAST}, {"LAST_ROW", TK_LAST_ROW},
{"LAST_ROW", TK_LAST_ROW}, {"LICENCE", TK_LICENCE},
{"LICENCE", TK_LICENCE}, {"LIKE", TK_LIKE},
{"LIKE", TK_LIKE}, {"LIMIT", TK_LIMIT},
{"LIMIT", TK_LIMIT}, {"LINEAR", TK_LINEAR},
{"LINEAR", TK_LINEAR}, {"LOCAL", TK_LOCAL},
{"LOCAL", TK_LOCAL}, {"MATCH", TK_MATCH},
{"MATCH", TK_MATCH}, {"MAXROWS", TK_MAXROWS},
{"MAXROWS", TK_MAXROWS}, {"MINROWS", TK_MINROWS},
{"MINROWS", TK_MINROWS}, {"MINUS", TK_MINUS},
{"MINUS", TK_MINUS}, {"MNODE", TK_MNODE},
{"MNODE", TK_MNODE}, {"MNODES", TK_MNODES},
{"MNODES", TK_MNODES}, {"MODIFY", TK_MODIFY},
{"MODIFY", TK_MODIFY}, {"MODULES", TK_MODULES},
{"MODULES", TK_MODULES}, {"NCHAR", TK_NCHAR},
{"NCHAR", TK_NCHAR}, {"NEXT", TK_NEXT},
{"NMATCH", TK_NMATCH}, {"NMATCH", TK_NMATCH},
{"NONE", TK_NONE}, {"NONE", TK_NONE},
{"NOT", TK_NOT}, {"NOT", TK_NOT},
{"NOW", TK_NOW}, {"NOW", TK_NOW},
{"NULL", TK_NULL}, {"NULL", TK_NULL},
{"NULLS", TK_NULLS}, {"NULLS", TK_NULLS},
{"OFFSET", TK_OFFSET}, {"OFFSET", TK_OFFSET},
{"ON", TK_ON}, {"ON", TK_ON},
{"OR", TK_OR}, {"OR", TK_OR},
{"ORDER", TK_ORDER}, {"ORDER", TK_ORDER},
{"OUTPUTTYPE", TK_OUTPUTTYPE}, {"OUTPUTTYPE", TK_OUTPUTTYPE},
{"PARTITION", TK_PARTITION}, {"PARTITION", TK_PARTITION},
{"PASS", TK_PASS}, {"PASS", TK_PASS},
{"PAGES", TK_PAGES}, {"PAGES", TK_PAGES},
{"PAGESIZE", TK_PAGESIZE}, {"PAGESIZE", TK_PAGESIZE},
{"PORT", TK_PORT}, {"PORT", TK_PORT},
{"PPS", TK_PPS}, {"PPS", TK_PPS},
{"PRECISION", TK_PRECISION}, {"PRECISION", TK_PRECISION},
{"PRIVILEGE", TK_PRIVILEGE}, {"PRIVILEGE", TK_PRIVILEGE},
{"PREV", TK_PREV}, {"PREV", TK_PREV},
{"QNODE", TK_QNODE}, {"QNODE", TK_QNODE},
{"QNODES", TK_QNODES}, {"QNODES", TK_QNODES},
{"QTIME", TK_QTIME}, {"QTIME", TK_QTIME},
{"QUERIES", TK_QUERIES}, {"QUERIES", TK_QUERIES},
{"QUERY", TK_QUERY}, {"QUERY", TK_QUERY},
// {"QUORUM", TK_QUORUM}, {"RATIO", TK_RATIO},
{"RATIO", TK_RATIO}, {"REPLICA", TK_REPLICA},
{"REPLICA", TK_REPLICA}, {"RESET", TK_RESET},
{"RESET", TK_RESET}, {"RETENTIONS", TK_RETENTIONS},
{"RETENTIONS", TK_RETENTIONS}, {"ROLLUP", TK_ROLLUP},
{"ROLLUP", TK_ROLLUP}, {"SCHEMA", TK_SCHEMA},
{"SCHEMA", TK_SCHEMA}, {"SCORES", TK_SCORES},
{"SCORES", TK_SCORES}, {"SELECT", TK_SELECT},
{"SELECT", TK_SELECT}, {"SESSION", TK_SESSION},
{"SESSION", TK_SESSION}, {"SET", TK_SET},
{"SET", TK_SET}, {"SHOW", TK_SHOW},
{"SHOW", TK_SHOW},
{"SINGLE_STABLE", TK_SINGLE_STABLE}, {"SINGLE_STABLE", TK_SINGLE_STABLE},
{"SLIDING", TK_SLIDING}, {"SLIDING", TK_SLIDING},
{"SLIMIT", TK_SLIMIT}, {"SLIMIT", TK_SLIMIT},
{"SMA", TK_SMA}, {"SMA", TK_SMA},
{"SMALLINT", TK_SMALLINT}, {"SMALLINT", TK_SMALLINT},
{"SNODE", TK_SNODE}, {"SNODE", TK_SNODE},
{"SNODES", TK_SNODES}, {"SNODES", TK_SNODES},
{"SOFFSET", TK_SOFFSET}, {"SOFFSET", TK_SOFFSET},
{"STABLE", TK_STABLE}, {"STABLE", TK_STABLE},
{"STABLES", TK_STABLES}, {"STABLES", TK_STABLES},
{"STATE", TK_STATE}, {"STATE", TK_STATE},
{"STATE_WINDOW", TK_STATE_WINDOW}, {"STATE_WINDOW", TK_STATE_WINDOW},
{"STORAGE", TK_STORAGE}, {"STORAGE", TK_STORAGE},
{"STREAM", TK_STREAM}, {"STREAM", TK_STREAM},
{"STREAMS", TK_STREAMS}, {"STREAMS", TK_STREAMS},
// {"STREAM_MODE", TK_STREAM_MODE}, {"STRICT", TK_STRICT},
{"STRICT", TK_STRICT}, {"SYNCDB", TK_SYNCDB},
{"SYNCDB", TK_SYNCDB}, {"TABLE", TK_TABLE},
{"TABLE", TK_TABLE}, {"TABLES", TK_TABLES},
{"TABLES", TK_TABLES}, {"TAG", TK_TAG},
{"TAG", TK_TAG}, {"TAGS", TK_TAGS},
{"TAGS", TK_TAGS}, {"TBNAME", TK_TBNAME},
{"TBNAME", TK_TBNAME}, {"TIMESTAMP", TK_TIMESTAMP},
{"TIMESTAMP", TK_TIMESTAMP}, {"TIMEZONE", TK_TIMEZONE},
{"TIMEZONE", TK_TIMEZONE}, {"TINYINT", TK_TINYINT},
{"TINYINT", TK_TINYINT}, {"TODAY", TK_TODAY},
{"TODAY", TK_TODAY}, {"TOPIC", TK_TOPIC},
{"TOPIC", TK_TOPIC}, {"TOPICS", TK_TOPICS},
{"TOPICS", TK_TOPICS}, {"TRIGGER", TK_TRIGGER},
{"TRIGGER", TK_TRIGGER}, {"TSERIES", TK_TSERIES},
{"TSERIES", TK_TSERIES}, {"TTL", TK_TTL},
{"TTL", TK_TTL}, {"UNION", TK_UNION},
{"UNION", TK_UNION}, {"UNSIGNED", TK_UNSIGNED},
{"UNSIGNED", TK_UNSIGNED}, {"USE", TK_USE},
{"USE", TK_USE}, {"USER", TK_USER},
{"USER", TK_USER}, {"USERS", TK_USERS},
{"USERS", TK_USERS}, {"USING", TK_USING},
{"USING", TK_USING}, {"VALUE", TK_VALUE},
{"VALUE", TK_VALUE}, {"VALUES", TK_VALUES},
{"VALUES", TK_VALUES}, {"VARCHAR", TK_VARCHAR},
{"VARCHAR", TK_VARCHAR}, {"VARIABLES", TK_VARIABLES},
{"VARIABLES", TK_VARIABLES}, {"VERBOSE", TK_VERBOSE},
{"VERBOSE", TK_VERBOSE}, {"VGROUPS", TK_VGROUPS},
{"VGROUPS", TK_VGROUPS}, {"VNODES", TK_VNODES},
{"VNODES", TK_VNODES}, {"WAL", TK_WAL},
{"WAL", TK_WAL}, {"WATERMARK", TK_WATERMARK},
{"WATERMARK", TK_WATERMARK}, {"WHERE", TK_WHERE},
{"WHERE", TK_WHERE}, {"WINDOW_CLOSE", TK_WINDOW_CLOSE},
{"WINDOW_CLOSE", TK_WINDOW_CLOSE}, {"WITH", TK_WITH},
{"WITH", TK_WITH}, {"_QENDTS", TK_QENDTS},
{"_QENDTS", TK_QENDTS}, {"_QSTARTTS", TK_QSTARTTS},
{"_QSTARTTS", TK_QSTARTTS}, {"_ROWTS", TK_ROWTS},
{"_ROWTS", TK_ROWTS}, {"_WDURATION", TK_WDURATION},
{"_WDURATION", TK_WDURATION}, {"_WENDTS", TK_WENDTS},
{"_WENDTS", TK_WENDTS}, {"_WSTARTTS", TK_WSTARTTS},
{"_WSTARTTS", TK_WSTARTTS},
// {"ID", TK_ID}, // {"ID", TK_ID},
// {"STRING", TK_STRING}, // {"STRING", TK_STRING},
// {"EQ", TK_EQ}, // {"EQ", TK_EQ},
@ -279,6 +278,7 @@ static SKeyword keywordTable[] = {
// {"PARTITIONS", TK_PARTITIONS}, // {"PARTITIONS", TK_PARTITIONS},
// {"MODE", TK_MODE}, // {"MODE", TK_MODE},
}; };
// clang-format on
static const char isIdChar[] = { static const char isIdChar[] = {
/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */

View File

@ -24,170 +24,179 @@ class ParserSelectTest : public ParserTestBase {};
TEST_F(ParserSelectTest, basic) { TEST_F(ParserSelectTest, basic) {
useDb("root", "test"); useDb("root", "test");
run("select * from t1"); run("SELECT * FROM t1");
run("select * from test.t1"); run("SELECT * FROM test.t1");
run("select ts, c1 from t1"); run("SELECT ts, c1 FROM t1");
run("select ts, t.c1 from (select * from t1) t"); run("SELECT ts, t.c1 FROM (SELECT * FROM t1) t");
run("select * from t1 tt1, t1 tt2 where tt1.c1 = tt2.c1"); run("SELECT * FROM t1 tt1, t1 tt2 where tt1.c1 = tt2.c1");
} }
TEST_F(ParserSelectTest, constant) { TEST_F(ParserSelectTest, constant) {
useDb("root", "test"); useDb("root", "test");
run("select 123, 20.4, 'abc', \"wxy\", timestamp '2022-02-09 17:30:20', true, false, 10s from t1"); run("SELECT 123, 20.4, 'abc', \"wxy\", timestamp '2022-02-09 17:30:20', true, false, 10s FROM t1");
run("select 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc', \"wxy\", " run("SELECT 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc', \"wxy\", "
"timestamp '2022-02-09 17:30:20', true, false, 15s from t1"); "timestamp '2022-02-09 17:30:20', true, false, 15s FROM t1");
run("select 123 + 45 from t1 where 2 - 1"); run("SELECT 123 + 45 FROM t1 where 2 - 1");
} }
TEST_F(ParserSelectTest, expression) { TEST_F(ParserSelectTest, expression) {
useDb("root", "test"); useDb("root", "test");
run("select ts + 10s, c1 + 10, concat(c2, 'abc') from t1"); run("SELECT ts + 10s, c1 + 10, concat(c2, 'abc') FROM t1");
run("select ts > 0, c1 < 20 and c2 = 'qaz' from t1"); run("SELECT ts > 0, c1 < 20 and c2 = 'qaz' FROM t1");
run("select ts > 0, c1 between 10 and 20 and c2 = 'qaz' from t1"); run("SELECT ts > 0, c1 between 10 and 20 and c2 = 'qaz' FROM t1");
} }
TEST_F(ParserSelectTest, condition) { TEST_F(ParserSelectTest, condition) {
useDb("root", "test"); useDb("root", "test");
run("select c1 from t1 where ts in (true, false)"); run("SELECT c1 FROM t1 where ts in (true, false)");
run("select * from t1 where c1 > 10 and c1 is not null"); run("SELECT * FROM t1 where c1 > 10 and c1 is not null");
} }
TEST_F(ParserSelectTest, pseudoColumn) { TEST_F(ParserSelectTest, pseudoColumn) {
useDb("root", "test"); useDb("root", "test");
run("select _wstartts, _wendts, count(*) from t1 interval(10s)"); run("SELECT _wstartts, _wendts, COUNT(*) FROM t1 INTERVAL(10s)");
} }
TEST_F(ParserSelectTest, multiResFunc) { TEST_F(ParserSelectTest, multiResFunc) {
useDb("root", "test"); useDb("root", "test");
run("select last(*), first(*), last_row(*) from t1"); run("SELECT last(*), first(*), last_row(*) FROM t1");
run("select last(c1, c2), first(t1.*), last_row(c3) from t1"); run("SELECT last(c1, c2), first(t1.*), last_row(c3) FROM t1");
run("select last(t2.*), first(t1.c1, t2.*), last_row(t1.*, t2.*) from st1s1 t1, st1s2 t2 where t1.ts = t2.ts"); run("SELECT last(t2.*), first(t1.c1, t2.*), last_row(t1.*, t2.*) FROM st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
} }
TEST_F(ParserSelectTest, timelineFunc) { TEST_F(ParserSelectTest, timelineFunc) {
useDb("root", "test"); useDb("root", "test");
run("select last(*), first(*) from t1"); run("SELECT last(*), first(*) FROM t1");
run("select last(*), first(*) from t1 group by c1"); run("SELECT last(*), first(*) FROM t1 group by c1");
run("select last(*), first(*) from t1 interval(10s)"); run("SELECT last(*), first(*) FROM t1 INTERVAL(10s)");
run("select diff(c1) from t1"); run("SELECT diff(c1) FROM t1");
} }
TEST_F(ParserSelectTest, clause) { TEST_F(ParserSelectTest, clause) {
useDb("root", "test"); useDb("root", "test");
// group by clause // group by clause
run("select count(*) cnt from t1 where c1 > 0"); run("SELECT COUNT(*) cnt FROM t1 where c1 > 0");
run("select count(*), c2 cnt from t1 where c1 > 0 group by c2"); run("SELECT COUNT(*), c2 cnt FROM t1 where c1 > 0 group by c2");
run("select count(*) cnt from t1 where c1 > 0 group by c2 having count(c1) > 10"); run("SELECT COUNT(*) cnt FROM t1 where c1 > 0 group by c2 having COUNT(c1) > 10");
run("select count(*), c1, c2 + 10, c1 + c2 cnt from t1 where c1 > 0 group by c2, c1"); run("SELECT COUNT(*), c1, c2 + 10, c1 + c2 cnt FROM t1 where c1 > 0 group by c2, c1");
run("select count(*), c1 + 10, c2 cnt from t1 where c1 > 0 group by c1 + 10, c2"); run("SELECT COUNT(*), c1 + 10, c2 cnt FROM t1 where c1 > 0 group by c1 + 10, c2");
// order by clause // order by clause
run("select count(*) cnt from t1 where c1 > 0 group by c2 order by cnt"); run("SELECT COUNT(*) cnt FROM t1 where c1 > 0 group by c2 order by cnt");
run("select count(*) cnt from t1 where c1 > 0 group by c2 order by 1"); run("SELECT COUNT(*) cnt FROM t1 where c1 > 0 group by c2 order by 1");
// distinct clause // distinct clause
// run("select distinct c1, c2 from t1 where c1 > 0 order by c1"); // run("SELECT distinct c1, c2 FROM t1 where c1 > 0 order by c1");
// run("select distinct c1 + 10, c2 from t1 where c1 > 0 order by c1 + 10, c2"); // run("SELECT distinct c1 + 10, c2 FROM t1 where c1 > 0 order by c1 + 10, c2");
// run("select distinct c1 + 10 cc1, c2 cc2 from t1 where c1 > 0 order by cc1, c2"); // run("SELECT distinct c1 + 10 cc1, c2 cc2 FROM t1 where c1 > 0 order by cc1, c2");
// run("select distinct count(c2) from t1 where c1 > 0 group by c1 order by count(c2)"); // run("SELECT distinct COUNT(c2) FROM t1 where c1 > 0 group by c1 order by COUNT(c2)");
} }
TEST_F(ParserSelectTest, window) { // INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [FILL(fill_mod_and_val)]
// fill_mod_and_val = { NONE | PREV | NULL | LINEAR | NEXT | value_mod }
// value_mod = VALUE , val ...
TEST_F(ParserSelectTest, interval) {
useDb("root", "test"); useDb("root", "test");
// INTERVAL(interval_val)
run("select count(*) from t1 interval(10s)"); run("SELECT COUNT(*) FROM t1 INTERVAL(10s)");
// INTERVAL(interval_val, interval_offset)
run("SELECT COUNT(*) FROM t1 INTERVAL(10s, 5s)");
// INTERVAL(interval_val, interval_offset) SLIDING (sliding_val)
run("SELECT COUNT(*) FROM t1 INTERVAL(10s, 5s) SLIDING(7s)");
// INTERVAL(interval_val) FILL(NONE)
run("SELECT COUNT(*) FROM t1 INTERVAL(10s) FILL(NONE)");
} }
TEST_F(ParserSelectTest, semanticError) { TEST_F(ParserSelectTest, semanticError) {
useDb("root", "test"); useDb("root", "test");
// TSDB_CODE_PAR_INVALID_COLUMN // TSDB_CODE_PAR_INVALID_COLUMN
run("select c1, cc1 from t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE); run("SELECT c1, cc1 FROM t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE);
run("select t1.c1, t1.cc1 from t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE); run("SELECT t1.c1, t1.cc1 FROM t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_TABLE_NOT_EXIST // TSDB_CODE_PAR_TABLE_NOT_EXIST
run("select * from t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE); run("SELECT * FROM t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
run("select * from test.t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE); run("SELECT * FROM test.t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
run("select t2.c1 from t1", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE); run("SELECT t2.c1 FROM t1", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_AMBIGUOUS_COLUMN // TSDB_CODE_PAR_AMBIGUOUS_COLUMN
run("select c2 from t1 tt1, t1 tt2 where tt1.c1 = tt2.c1", TSDB_CODE_PAR_AMBIGUOUS_COLUMN, PARSER_STAGE_TRANSLATE); run("SELECT c2 FROM t1 tt1, t1 tt2 where tt1.c1 = tt2.c1", TSDB_CODE_PAR_AMBIGUOUS_COLUMN, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_WRONG_VALUE_TYPE // TSDB_CODE_PAR_WRONG_VALUE_TYPE
run("select timestamp '2010' from t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE, PARSER_STAGE_TRANSLATE); run("SELECT timestamp '2010' FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION // TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
run("select c2 from t1 tt1 join t1 tt2 on count(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, run("SELECT c2 FROM t1 tt1 join t1 tt2 on COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION,
PARSER_STAGE_TRANSLATE); PARSER_STAGE_TRANSLATE);
run("select c2 from t1 where count(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE); run("SELECT c2 FROM t1 where COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
run("select c2 from t1 group by count(*)", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE); run("SELECT c2 FROM t1 group by COUNT(*)", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT // TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT
run("select c2 from t1 order by 0", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE); run("SELECT c2 FROM t1 order by 0", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE);
run("select c2 from t1 order by 2", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE); run("SELECT c2 FROM t1 order by 2", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION // TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
run("select count(*) cnt from t1 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, PARSER_STAGE_TRANSLATE); run("SELECT COUNT(*) cnt FROM t1 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, PARSER_STAGE_TRANSLATE);
run("select count(*) cnt from t1 group by c2 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, run("SELECT COUNT(*) cnt FROM t1 group by c2 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
PARSER_STAGE_TRANSLATE); PARSER_STAGE_TRANSLATE);
run("select count(*), c1 cnt from t1 group by c2 having c2 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, run("SELECT COUNT(*), c1 cnt FROM t1 group by c2 having c2 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
PARSER_STAGE_TRANSLATE); PARSER_STAGE_TRANSLATE);
run("select count(*) cnt from t1 group by c2 having c2 > 0 order by c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, run("SELECT COUNT(*) cnt FROM t1 group by c2 having c2 > 0 order by c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION,
PARSER_STAGE_TRANSLATE); PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_NOT_SINGLE_GROUP // TSDB_CODE_PAR_NOT_SINGLE_GROUP
run("select count(*), c1 from t1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE); run("SELECT COUNT(*), c1 FROM t1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
run("select count(*) from t1 order by c1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE); run("SELECT COUNT(*) FROM t1 order by c1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
run("select c1 from t1 order by count(*)", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE); run("SELECT c1 FROM t1 order by COUNT(*)", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE);
// TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION // TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
run("select distinct c1, c2 from t1 where c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION, run("SELECT distinct c1, c2 FROM t1 where c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
PARSER_STAGE_TRANSLATE); PARSER_STAGE_TRANSLATE);
run("select distinct c1 from t1 where c1 > 0 order by count(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION, run("SELECT distinct c1 FROM t1 where c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
PARSER_STAGE_TRANSLATE); PARSER_STAGE_TRANSLATE);
run("select distinct c2 from t1 where c1 > 0 order by count(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION, run("SELECT distinct c2 FROM t1 where c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION,
PARSER_STAGE_TRANSLATE); PARSER_STAGE_TRANSLATE);
} }

View File

@ -274,7 +274,7 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = nodesCollectFuncs(pSelect, fmIsScanPseudoColumnFunc, &pScan->pScanPseudoCols); code = nodesCollectFuncs(pSelect, SQL_CLAUSE_FROM, fmIsScanPseudoColumnFunc, &pScan->pScanPseudoCols);
} }
pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->pMeta); pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->pMeta);
@ -440,7 +440,7 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
} }
if (TSDB_CODE_SUCCESS == code && pSelect->hasAggFuncs) { if (TSDB_CODE_SUCCESS == code && pSelect->hasAggFuncs) {
code = nodesCollectFuncs(pSelect, fmIsAggFunc, &pAgg->pAggFuncs); code = nodesCollectFuncs(pSelect, SQL_CLAUSE_GROUP_BY, fmIsAggFunc, &pAgg->pAggFuncs);
} }
// rewrite the expression in subsequent clauses // rewrite the expression in subsequent clauses
@ -474,7 +474,7 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SWindowLogicNode* pWindow, static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SWindowLogicNode* pWindow,
SLogicNode** pLogicNode) { SLogicNode** pLogicNode) {
int32_t code = nodesCollectFuncs(pSelect, fmIsWindowClauseFunc, &pWindow->pFuncs); int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_WINDOW, fmIsWindowClauseFunc, &pWindow->pFuncs);
if (pCxt->pPlanCxt->streamQuery) { if (pCxt->pPlanCxt->streamQuery) {
pWindow->triggerType = pCxt->pPlanCxt->triggerType; pWindow->triggerType = pCxt->pPlanCxt->triggerType;
@ -559,14 +559,6 @@ static int32_t createWindowLogicNodeByInterval(SLogicPlanContext* pCxt, SInterva
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
if (NULL != pInterval->pFill) {
pWindow->pFill = nodesCloneNode(pInterval->pFill);
if (NULL == pWindow->pFill) {
nodesDestroyNode(pWindow);
return TSDB_CODE_OUT_OF_MEMORY;
}
}
return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode); return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
} }
@ -589,6 +581,37 @@ static int32_t createWindowLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
return TSDB_CODE_FAILED; return TSDB_CODE_FAILED;
} }
static int32_t createFillLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
if (NULL == pSelect->pWindow || QUERY_NODE_INTERVAL_WINDOW != nodeType(pSelect->pWindow) ||
NULL == ((SIntervalWindowNode*)pSelect->pWindow)->pFill) {
return TSDB_CODE_SUCCESS;
}
SFillNode* pFillNode = (SFillNode*)(((SIntervalWindowNode*)pSelect->pWindow)->pFill);
SFillLogicNode* pFill = nodesMakeNode(QUERY_NODE_LOGIC_PLAN_FILL);
if (NULL == pFill) {
return TSDB_CODE_OUT_OF_MEMORY;
}
int32_t code = nodesCollectColumns(pSelect, SQL_CLAUSE_WINDOW, NULL, COLLECT_COL_TYPE_ALL, &pFill->node.pTargets);
pFill->mode = pFillNode->mode;
pFill->pValues = nodesCloneNode(pFillNode->pValues);
pFill->pWStartTs = nodesCloneNode(pFillNode->pWStartTs);
if ((NULL != pFillNode->pValues && NULL == pFill->pValues) || NULL == pFill->pWStartTs) {
code = TSDB_CODE_OUT_OF_MEMORY;
}
if (TSDB_CODE_SUCCESS == code) {
*pLogicNode = (SLogicNode*)pFill;
} else {
nodesDestroyNode(pFill);
}
return code;
}
static int32_t createSortLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) { static int32_t createSortLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
if (NULL == pSelect->pOrderByList) { if (NULL == pSelect->pOrderByList) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
@ -753,6 +776,9 @@ static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = createChildLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot); code = createChildLogicNode(pCxt, pSelect, createWindowLogicNode, &pRoot);
} }
if (TSDB_CODE_SUCCESS == code) {
code = createChildLogicNode(pCxt, pSelect, createFillLogicNode, &pRoot);
}
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = createChildLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot); code = createChildLogicNode(pCxt, pSelect, createAggLogicNode, &pRoot);
} }

View File

@ -17,8 +17,8 @@
#include "catalog.h" #include "catalog.h"
#include "functionMgt.h" #include "functionMgt.h"
#include "tglobal.h"
#include "systable.h" #include "systable.h"
#include "tglobal.h"
typedef struct SSlotIdInfo { typedef struct SSlotIdInfo {
int16_t slotId; int16_t slotId;
@ -880,12 +880,6 @@ static int32_t createIntervalPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChil
pInterval->intervalUnit = pWindowLogicNode->intervalUnit; pInterval->intervalUnit = pWindowLogicNode->intervalUnit;
pInterval->slidingUnit = pWindowLogicNode->slidingUnit; pInterval->slidingUnit = pWindowLogicNode->slidingUnit;
pInterval->pFill = nodesCloneNode(pWindowLogicNode->pFill);
if (NULL != pWindowLogicNode->pFill && NULL == pInterval->pFill) {
nodesDestroyNode(pInterval);
return TSDB_CODE_OUT_OF_MEMORY;
}
return createWindowPhysiNodeFinalize(pCxt, pChildren, &pInterval->window, pWindowLogicNode, pPhyNode); return createWindowPhysiNodeFinalize(pCxt, pChildren, &pInterval->window, pWindowLogicNode, pPhyNode);
} }
@ -1035,6 +1029,43 @@ static int32_t createPartitionPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChi
return code; return code;
} }
static int32_t createFillPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SFillLogicNode* pFillNode,
SPhysiNode** pPhyNode) {
SFillPhysiNode* pFill = (SFillPhysiNode*)makePhysiNode(pCxt, getPrecision(pChildren), (SLogicNode*)pFillNode,
QUERY_NODE_PHYSICAL_PLAN_FILL);
if (NULL == pFill) {
return TSDB_CODE_OUT_OF_MEMORY;
}
SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc);
int32_t code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pFillNode->node.pTargets, &pFill->pTargets);
if (TSDB_CODE_SUCCESS == code) {
code = addDataBlockSlots(pCxt, pFill->pTargets, pFill->node.pOutputDataBlockDesc);
}
if (TSDB_CODE_SUCCESS == code) {
pFill->pWStartTs = nodesCloneNode(pFillNode->pWStartTs);
if (NULL == pFill->pWStartTs) {
code = TSDB_CODE_OUT_OF_MEMORY;
}
}
if (TSDB_CODE_SUCCESS == code && NULL != pFillNode->pValues) {
pFill->pValues = nodesCloneNode(pFillNode->pValues);
if (NULL == pFill->pValues) {
code = TSDB_CODE_OUT_OF_MEMORY;
}
}
if (TSDB_CODE_SUCCESS == code) {
*pPhyNode = (SPhysiNode*)pFill;
} else {
nodesDestroyNode(pFill);
}
return code;
}
static int32_t doCreatePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode, SSubplan* pSubplan, static int32_t doCreatePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode, SSubplan* pSubplan,
SNodeList* pChildren, SPhysiNode** pPhyNode) { SNodeList* pChildren, SPhysiNode** pPhyNode) {
switch (nodeType(pLogicNode)) { switch (nodeType(pLogicNode)) {
@ -1054,6 +1085,8 @@ static int32_t doCreatePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode
return createSortPhysiNode(pCxt, pChildren, (SSortLogicNode*)pLogicNode, pPhyNode); return createSortPhysiNode(pCxt, pChildren, (SSortLogicNode*)pLogicNode, pPhyNode);
case QUERY_NODE_LOGIC_PLAN_PARTITION: case QUERY_NODE_LOGIC_PLAN_PARTITION:
return createPartitionPhysiNode(pCxt, pChildren, (SPartitionLogicNode*)pLogicNode, pPhyNode); return createPartitionPhysiNode(pCxt, pChildren, (SPartitionLogicNode*)pLogicNode, pPhyNode);
case QUERY_NODE_LOGIC_PLAN_FILL:
return createFillPhysiNode(pCxt, pChildren, (SFillLogicNode*)pLogicNode, pPhyNode);
default: default:
break; break;
} }

View File

@ -23,19 +23,19 @@ class PlanIntervalTest : public PlannerTestBase {};
TEST_F(PlanIntervalTest, basic) { TEST_F(PlanIntervalTest, basic) {
useDb("root", "test"); useDb("root", "test");
run("select count(*) from t1 interval(10s)"); run("SELECT COUNT(*) FROM t1 INTERVAL(10s)");
} }
TEST_F(PlanIntervalTest, pseudoCol) { TEST_F(PlanIntervalTest, pseudoCol) {
useDb("root", "test"); useDb("root", "test");
run("select _wstartts, _wduration, _wendts, count(*) from t1 interval(10s)"); run("SELECT _WSTARTTS, _WDURATION, _WENDTS, COUNT(*) FROM t1 INTERVAL(10s)");
} }
TEST_F(PlanIntervalTest, fill) { TEST_F(PlanIntervalTest, fill) {
useDb("root", "test"); useDb("root", "test");
run("select count(*) from t1 interval(10s) fill(linear)"); run("SELECT COUNT(*) FROM t1 INTERVAL(10s) FILL(LINEAR)");
run("select count(*), sum(c1) from t1 interval(10s) fill(value, 10, 20)"); run("SELECT COUNT(*), sum(c1) FROM t1 INTERVAL(10s) FILL(VALUE, 10, 20)");
} }