diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index f052c9daa7..3e78da63de 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -190,6 +190,7 @@ typedef struct SLimitNode { typedef struct SStateWindowNode { ENodeType type; // QUERY_NODE_STATE_WINDOW + SNode* pCol; // timestamp primary key SNode* pExpr; } SStateWindowNode; diff --git a/source/libs/function/inc/builtins.h b/source/libs/function/inc/builtins.h index 2c0148e04f..f0349c55b9 100644 --- a/source/libs/function/inc/builtins.h +++ b/source/libs/function/inc/builtins.h @@ -26,15 +26,17 @@ extern "C" { #define FUNC_MGT_FUNC_CLASSIFICATION_MASK(n) (1 << n) -#define FUNC_MGT_AGG_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(0) -#define FUNC_MGT_SCALAR_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(1) -#define FUNC_MGT_NONSTANDARD_SQL_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(2) -#define FUNC_MGT_STRING_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(3) -#define FUNC_MGT_DATETIME_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(4) -#define FUNC_MGT_TIMELINE_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(5) -#define FUNC_MGT_TIMEORDER_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(6) -#define FUNC_MGT_PSEUDO_COLUMN_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(7) -#define FUNC_MGT_WINDOW_PC_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(8) +#define FUNC_MGT_AGG_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(0) +#define FUNC_MGT_SCALAR_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(1) +#define FUNC_MGT_NONSTANDARD_SQL_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(2) +#define FUNC_MGT_STRING_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(3) +#define FUNC_MGT_DATETIME_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(4) +#define FUNC_MGT_TIMELINE_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(5) +#define FUNC_MGT_TIMEORDER_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(6) +#define FUNC_MGT_PSEUDO_COLUMN_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(7) +#define FUNC_MGT_WINDOW_PC_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(8) +#define FUNC_MGT_SPECIAL_DATA_REQUIRED FUNC_MGT_FUNC_CLASSIFICATION_MASK(9) +#define FUNC_MGT_DYNAMIC_SCAN_OPTIMIZED FUNC_MGT_FUNC_CLASSIFICATION_MASK(10) #define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0) diff --git a/source/libs/nodes/src/nodesTraverseFuncs.c b/source/libs/nodes/src/nodesTraverseFuncs.c index 3c10287992..4a782cce08 100644 --- a/source/libs/nodes/src/nodesTraverseFuncs.c +++ b/source/libs/nodes/src/nodesTraverseFuncs.c @@ -77,9 +77,14 @@ static EDealRes walkNode(SNode* pNode, ETraversalOrder order, FNodeWalker walker case QUERY_NODE_ORDER_BY_EXPR: res = walkNode(((SOrderByExprNode*)pNode)->pExpr, order, walker, pContext); break; - case QUERY_NODE_STATE_WINDOW: - res = walkNode(((SStateWindowNode*)pNode)->pExpr, order, walker, pContext); + case QUERY_NODE_STATE_WINDOW: { + SStateWindowNode* pState = (SStateWindowNode*)pNode; + res = walkNode(pState->pExpr, order, walker, pContext); + if (DEAL_RES_ERROR != res) { + res = walkNode(pState->pCol, order, walker, pContext); + } break; + } case QUERY_NODE_SESSION_WINDOW: { SSessionWindowNode* pSession = (SSessionWindowNode*)pNode; res = walkNode(pSession->pCol, order, walker, pContext); @@ -211,12 +216,22 @@ static EDealRes rewriteNode(SNode** pRawNode, ETraversalOrder order, FNodeRewrit case QUERY_NODE_ORDER_BY_EXPR: res = rewriteNode(&(((SOrderByExprNode*)pNode)->pExpr), order, rewriter, pContext); break; - case QUERY_NODE_STATE_WINDOW: - res = rewriteNode(&(((SStateWindowNode*)pNode)->pExpr), order, rewriter, pContext); + case QUERY_NODE_STATE_WINDOW: { + SStateWindowNode* pState = (SStateWindowNode*)pNode; + res = rewriteNode(&pState->pExpr, order, rewriter, pContext); + if (DEAL_RES_ERROR != res) { + res = rewriteNode(&pState->pCol, order, rewriter, pContext); + } break; - case QUERY_NODE_SESSION_WINDOW: - res = rewriteNode(&(((SSessionWindowNode*)pNode)->pCol), order, rewriter, pContext); + } + case QUERY_NODE_SESSION_WINDOW: { + SSessionWindowNode* pSession = (SSessionWindowNode*)pNode; + res = rewriteNode(&pSession->pCol, order, rewriter, pContext); + if (DEAL_RES_ERROR != res) { + res = rewriteNode(&pSession->pGap, order, rewriter, pContext); + } break; + } case QUERY_NODE_INTERVAL_WINDOW: { SIntervalWindowNode* pInterval = (SIntervalWindowNode*)pNode; res = rewriteNode(&(pInterval->pInterval), order, rewriter, pContext); diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index 4908748f0d..01531f89ab 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -456,6 +456,13 @@ SNode* createSessionWindowNode(SAstCreateContext* pCxt, SNode* pCol, SNode* pGap SNode* createStateWindowNode(SAstCreateContext* pCxt, SNode* pExpr) { SStateWindowNode* state = (SStateWindowNode*)nodesMakeNode(QUERY_NODE_STATE_WINDOW); CHECK_OUT_OF_MEM(state); + state->pCol = nodesMakeNode(QUERY_NODE_COLUMN); + if (NULL == state->pCol) { + nodesDestroyNode(state); + CHECK_OUT_OF_MEM(state->pCol); + } + ((SColumnNode*)state->pCol)->colId = PRIMARYKEY_TIMESTAMP_COL_ID; + strcpy(((SColumnNode*)state->pCol)->colName, PK_TS_COL_INTERNAL_NAME); state->pExpr = pExpr; return (SNode*)state; } @@ -584,34 +591,6 @@ SNode* createDatabaseOptions(SAstCreateContext* pCxt) { return (SNode*)pOptions; } -static bool checkAndSetKeepOption(SAstCreateContext* pCxt, SNodeList* pKeep, int32_t* pKeep0, int32_t* pKeep1, int32_t* pKeep2) { - int32_t numOfKeep = LIST_LENGTH(pKeep); - if (numOfKeep > 3 || numOfKeep < 1) { - snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "invalid number of keep options"); - return false; - } - - int32_t daysToKeep0 = strtol(((SValueNode*)nodesListGetNode(pKeep, 0))->literal, NULL, 10); - int32_t daysToKeep1 = numOfKeep > 1 ? strtol(((SValueNode*)nodesListGetNode(pKeep, 1))->literal, NULL, 10) : daysToKeep0; - int32_t daysToKeep2 = numOfKeep > 2 ? strtol(((SValueNode*)nodesListGetNode(pKeep, 2))->literal, NULL, 10) : daysToKeep1; - if (daysToKeep0 < TSDB_MIN_KEEP || daysToKeep1 < TSDB_MIN_KEEP || daysToKeep2 < TSDB_MIN_KEEP || - daysToKeep0 > TSDB_MAX_KEEP || daysToKeep1 > TSDB_MAX_KEEP || daysToKeep2 > TSDB_MAX_KEEP) { - snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, - "invalid option keep: %d, %d, %d valid range: [%d, %d]", daysToKeep0, daysToKeep1, daysToKeep2, TSDB_MIN_KEEP, TSDB_MAX_KEEP); - return false; - } - - if (!((daysToKeep0 <= daysToKeep1) && (daysToKeep1 <= daysToKeep2))) { - snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "invalid keep value, should be keep0 <= keep1 <= keep2"); - return false; - } - - *pKeep0 = daysToKeep0; - *pKeep1 = daysToKeep1; - *pKeep2 = daysToKeep2; - return true; -} - SNode* setDatabaseAlterOption(SAstCreateContext* pCxt, SNode* pOptions, SAlterOption* pAlterOption) { switch (pAlterOption->type) { case DB_OPTION_BLOCKS: diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index 596bb64bac..bd5ce0f494 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -488,6 +488,12 @@ static int32_t createWindowLogicNodeByState(SLogicPlanContext* pCxt, SStateWindo pWindow->winType = WINDOW_TYPE_STATE; pWindow->pStateExpr = nodesCloneNode(pState->pExpr); + pWindow->pTspk = nodesCloneNode(pState->pCol); + if (NULL == pWindow->pTspk) { + nodesDestroyNode(pWindow); + return TSDB_CODE_OUT_OF_MEMORY; + } + return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode); } @@ -500,6 +506,12 @@ static int32_t createWindowLogicNodeBySession(SLogicPlanContext* pCxt, SSessionW pWindow->winType = WINDOW_TYPE_SESSION; pWindow->sessionGap = ((SValueNode*)pSession->pGap)->datum.i; + pWindow->pTspk = nodesCloneNode(pSession->pCol); + if (NULL == pWindow->pTspk) { + nodesDestroyNode(pWindow); + return TSDB_CODE_OUT_OF_MEMORY; + } + return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode); } diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 3b255bf276..f34452f84a 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -1238,6 +1238,7 @@ static void setExplainInfo(SPlanContext* pCxt, SQueryPlan* pPlan) { SExplainStmt* pStmt = (SExplainStmt*)pCxt->pAstRoot; pPlan->explainInfo.mode = pStmt->analyze ? EXPLAIN_MODE_ANALYZE : EXPLAIN_MODE_STATIC; pPlan->explainInfo.verbose = pStmt->pOptions->verbose; + pPlan->explainInfo.ratio = pStmt->pOptions->ratio; } else { pPlan->explainInfo.mode = EXPLAIN_MODE_DISABLE; }