From e070ad2b77b6e85d3afa83698d27ce20569ea725 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Fri, 11 Feb 2022 09:19:31 -0500 Subject: [PATCH 1/2] TD-13495 planner refactoring --- include/libs/function/functionMgt.h | 7 +- include/libs/nodes/nodes.h | 11 +- include/libs/nodes/querynodes.h | 17 +- include/util/taoserror.h | 1 + source/libs/function/src/functionMgt.c | 21 ++- source/libs/nodes/src/nodesCloneFuncs.c | 175 ++++++++++++++++++- source/libs/nodes/src/nodesCodeFuncs.c | 1 - source/libs/nodes/src/nodesEqualFuncs.c | 8 - source/libs/nodes/src/nodesTraverseFuncs.c | 6 - source/libs/nodes/src/nodesUtilFuncs.c | 2 - source/libs/parser/inc/astCreateFuncs.h | 1 - source/libs/parser/inc/new_sql.y | 4 +- source/libs/parser/inc/parserImpl.h | 15 +- source/libs/parser/src/astCreateFuncs.c | 18 +- source/libs/parser/src/new_sql.c | 4 +- source/libs/parser/src/parserImpl.c | 111 ++++++++---- source/libs/planner/CMakeLists.txt | 2 +- source/libs/planner/inc/plannerImpl.h | 27 +++ source/libs/planner/src/plannerImpl.c | 189 ++++++++++++++++++++- 19 files changed, 523 insertions(+), 97 deletions(-) diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index c3c8b5c4ce..69673804fe 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -105,7 +105,6 @@ typedef struct SFuncExecEnv { int32_t calcMemSize; } SFuncExecEnv; -typedef void* FuncMgtHandle; typedef bool (*FExecGetEnv)(SFunctionNode* pFunc, SFuncExecEnv* pEnv); typedef bool (*FExecInit)(struct SqlFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo); typedef void (*FExecProcess)(struct SqlFunctionCtx *pCtx); @@ -120,9 +119,7 @@ typedef struct SFuncExecFuncs { int32_t fmFuncMgtInit(); -int32_t fmGetHandle(FuncMgtHandle* pHandle); - -int32_t fmGetFuncInfo(FuncMgtHandle handle, const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType); +int32_t fmGetFuncInfo(const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType); int32_t fmGetFuncResultType(SFunctionNode* pFunc); @@ -136,7 +133,7 @@ bool fmIsTimeorderFunc(int32_t funcId); int32_t fmFuncScanType(int32_t funcId); -int32_t fmGetFuncExecFuncs(FuncMgtHandle handle, int32_t funcId, SFuncExecFuncs* pFpSet); +int32_t fmGetFuncExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet); #ifdef __cplusplus } diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 321190d254..068b80cf59 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -49,7 +49,6 @@ typedef enum ENodeType { QUERY_NODE_VALUE, QUERY_NODE_OPERATOR, QUERY_NODE_LOGIC_CONDITION, - QUERY_NODE_IS_NULL_CONDITION, QUERY_NODE_FUNCTION, QUERY_NODE_REAL_TABLE, QUERY_NODE_TEMP_TABLE, @@ -62,6 +61,7 @@ typedef enum ENodeType { QUERY_NODE_INTERVAL_WINDOW, QUERY_NODE_NODE_LIST, QUERY_NODE_FILL, + QUERY_NODE_COLUMN_REF, // Only be used in parser module. QUERY_NODE_RAW_EXPR, @@ -69,7 +69,11 @@ typedef enum ENodeType { // Statement nodes are used in parser and planner module. QUERY_NODE_SET_OPERATOR, QUERY_NODE_SELECT_STMT, - QUERY_NODE_SHOW_STMT + QUERY_NODE_SHOW_STMT, + + QUERY_NODE_LOGIC_PLAN_SCAN, + QUERY_NODE_LOGIC_PLAN_FILTER, + QUERY_NODE_LOGIC_PLAN_AGG } ENodeType; /** @@ -121,7 +125,8 @@ void nodesRewriteListPostOrder(SNodeList* pList, FNodeRewriter rewriter, void* p bool nodesEqualNode(const SNode* a, const SNode* b); -void nodesCloneNode(const SNode* pNode); +SNode* nodesCloneNode(const SNode* pNode); +SNodeList* nodesCloneList(const SNodeList* pList); int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen); int32_t nodesStringToNode(const char* pStr, SNode** pNode); diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index e1b16a7a1a..8a89a4fb6d 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -37,7 +37,7 @@ typedef struct SDataType { } SDataType; typedef struct SExprNode { - ENodeType nodeType; + ENodeType type; SDataType resType; char aliasName[TSDB_COL_NAME_LEN]; SNodeList* pAssociationList; @@ -59,6 +59,11 @@ typedef struct SColumnNode { SNode* pProjectRef; } SColumnNode; +typedef struct SColumnRef { + ENodeType type; + int32_t slotId; +} SColumnRef; + typedef struct SValueNode { SExprNode node; // QUERY_NODE_VALUE char* literal; @@ -93,6 +98,8 @@ typedef enum EOperatorType { OP_TYPE_NOT_LIKE, OP_TYPE_MATCH, OP_TYPE_NMATCH, + OP_TYPE_IS_NULL, + OP_TYPE_IS_NOT_NULL, // json operator OP_TYPE_JSON_GET_VALUE, @@ -118,12 +125,6 @@ typedef struct SLogicConditionNode { SNodeList* pParameterList; } SLogicConditionNode; -typedef struct SIsNullCondNode { - SExprNode node; // QUERY_NODE_IS_NULL_CONDITION - SNode* pExpr; - bool isNull; -} SIsNullCondNode; - typedef struct SNodeListNode { ENodeType type; // QUERY_NODE_NODE_LIST SNodeList* pNodeList; @@ -138,7 +139,7 @@ typedef struct SFunctionNode { } SFunctionNode; typedef struct STableNode { - ENodeType type; + SExprNode node; char dbName[TSDB_DB_NAME_LEN]; char tableName[TSDB_TABLE_NAME_LEN]; char tableAlias[TSDB_TABLE_NAME_LEN]; diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 0a822927ad..5c12d29b50 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -459,6 +459,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION TAOS_DEF_ERROR_CODE(0, 0x260A) //Not a GROUP BY expression #define TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION TAOS_DEF_ERROR_CODE(0, 0x260B) //Not SELECTed expression #define TSDB_CODE_PAR_NOT_SINGLE_GROUP TAOS_DEF_ERROR_CODE(0, 0x260C) //Not a single-group group function +#define TSDB_CODE_PAR_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x260D) //Out of memory #ifdef __cplusplus } diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c index 78d2feaa83..887f65a6ea 100644 --- a/source/libs/function/src/functionMgt.c +++ b/source/libs/function/src/functionMgt.c @@ -40,14 +40,8 @@ int32_t fmFuncMgtInit() { return TSDB_CODE_SUCCESS; } -int32_t fmGetHandle(FuncMgtHandle* pHandle) { - *pHandle = &gFunMgtService; - return TSDB_CODE_SUCCESS; -} - -int32_t fmGetFuncInfo(FuncMgtHandle handle, const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType) { - SFuncMgtService* pService = (SFuncMgtService*)handle; - void* pVal = taosHashGet(pService->pFuncNameHashTable, pFuncName, strlen(pFuncName)); +int32_t fmGetFuncInfo(const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType) { + void* pVal = taosHashGet(gFunMgtService.pFuncNameHashTable, pFuncName, strlen(pFuncName)); if (NULL == pVal) { return TSDB_CODE_FAILED; } @@ -66,6 +60,17 @@ int32_t fmGetFuncResultType(SFunctionNode* pFunc) { return funcMgtBuiltins[pFunc->funcId].checkFunc(pFunc); } +int32_t fmGetFuncExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet) { + if (funcId < 0 || funcId >= funcMgtBuiltinsNum) { + return TSDB_CODE_FAILED; + } + pFpSet->getEnv = funcMgtBuiltins[funcId].getEnvFunc; + pFpSet->init = funcMgtBuiltins[funcId].initFunc; + pFpSet->process = funcMgtBuiltins[funcId].processFunc; + pFpSet->finalize = funcMgtBuiltins[funcId].finalizeFunc; + return TSDB_CODE_SUCCESS; +} + bool fmIsAggFunc(int32_t funcId) { if (funcId < 0 || funcId >= funcMgtBuiltinsNum) { return false; diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index 2d0a6483ae..63bb11a821 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -13,8 +13,179 @@ * along with this program. If not, see . */ -#include "nodes.h" +#include "querynodes.h" +#include "taos.h" -void nodesCloneNode(const SNode* pNode) { +#define COPY_SCALAR_FIELD(fldname) \ + do { \ + (pDst)->fldname = (pSrc)->fldname; \ + } while (0) +#define COPY_CHAR_ARRAY_FIELD(fldname) \ + do { \ + strcpy((pDst)->fldname, (pSrc)->fldname); \ + } while (0) + +#define COPY_CHAR_POINT_FIELD(fldname) \ + do { \ + (pDst)->fldname = strdup((pSrc)->fldname); \ + } while (0) + +#define COPY_NODE_FIELD(fldname) \ + do { \ + (pDst)->fldname = nodesCloneNode((pSrc)->fldname); \ + if (NULL == (pDst)->fldname) { \ + nodesDestroyNode((SNode*)(pDst)); \ + return NULL; \ + } \ + } while (0) + +#define COPY_NODE_LIST_FIELD(fldname) \ + do { \ + (pDst)->fldname = nodesCloneList((pSrc)->fldname); \ + if (NULL == (pDst)->fldname) { \ + nodesDestroyNode((SNode*)(pDst)); \ + return NULL; \ + } \ + } while (0) + +static void dataTypeCopy(const SDataType* pSrc, SDataType* pDst) { + COPY_SCALAR_FIELD(type); + COPY_SCALAR_FIELD(precision); + COPY_SCALAR_FIELD(scale); + COPY_SCALAR_FIELD(bytes); +} + +static void exprNodeCopy(const SExprNode* pSrc, SExprNode* pDst) { + COPY_SCALAR_FIELD(type); + dataTypeCopy(&pSrc->resType, &pDst->resType); + COPY_CHAR_ARRAY_FIELD(aliasName); + // COPY_NODE_LIST_FIELD(pAssociationList); +} + +static SNode* columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) { + exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst); + COPY_SCALAR_FIELD(colId); + COPY_SCALAR_FIELD(colType); + COPY_CHAR_ARRAY_FIELD(dbName); + COPY_CHAR_ARRAY_FIELD(tableName); + COPY_CHAR_ARRAY_FIELD(tableAlias); + COPY_CHAR_ARRAY_FIELD(colName); + // COPY_NODE_FIELD(pProjectRef); + return (SNode*)pDst; +} + +static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) { + exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst); + COPY_CHAR_POINT_FIELD(literal); + COPY_SCALAR_FIELD(isDuration); + switch (pSrc->node.resType.type) { + case TSDB_DATA_TYPE_NULL: + break; + case TSDB_DATA_TYPE_BOOL: + COPY_SCALAR_FIELD(datum.b); + break; + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_INT: + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_TIMESTAMP: + COPY_SCALAR_FIELD(datum.i); + break; + case TSDB_DATA_TYPE_UTINYINT: + case TSDB_DATA_TYPE_USMALLINT: + case TSDB_DATA_TYPE_UINT: + case TSDB_DATA_TYPE_UBIGINT: + COPY_SCALAR_FIELD(datum.u); + break; + case TSDB_DATA_TYPE_FLOAT: + case TSDB_DATA_TYPE_DOUBLE: + COPY_SCALAR_FIELD(datum.d); + break; + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: + case TSDB_DATA_TYPE_VARCHAR: + case TSDB_DATA_TYPE_VARBINARY: + COPY_CHAR_POINT_FIELD(datum.p); + break; + case TSDB_DATA_TYPE_JSON: + case TSDB_DATA_TYPE_DECIMAL: + case TSDB_DATA_TYPE_BLOB: + // todo + default: + break; + } + return (SNode*)pDst; +} + +static SNode* operatorNodeCopy(const SOperatorNode* pSrc, SOperatorNode* pDst) { + exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst); + COPY_SCALAR_FIELD(opType); + COPY_NODE_FIELD(pLeft); + COPY_NODE_FIELD(pRight); + return (SNode*)pDst; +} + +static SNode* logicConditionNodeCopy(const SLogicConditionNode* pSrc, SLogicConditionNode* pDst) { + exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst); + COPY_SCALAR_FIELD(condType); + COPY_NODE_LIST_FIELD(pParameterList); + return (SNode*)pDst; +} + +static SNode* functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst) { + exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst); + COPY_CHAR_ARRAY_FIELD(functionName); + COPY_SCALAR_FIELD(funcId); + COPY_SCALAR_FIELD(funcType); + COPY_NODE_LIST_FIELD(pParameterList); + return (SNode*)pDst; +} + +SNode* nodesCloneNode(const SNode* pNode) { + if (NULL == pNode) { + return NULL; + } + SNode* pDst = nodesMakeNode(nodeType(pNode)); + if (NULL == pDst) { + return NULL; + } + switch (nodeType(pNode)) { + case QUERY_NODE_COLUMN: + return columnNodeCopy((const SColumnNode*)pNode, (SColumnNode*)pDst); + case QUERY_NODE_VALUE: + return valueNodeCopy((const SValueNode*)pNode, (SValueNode*)pDst); + case QUERY_NODE_OPERATOR: + return operatorNodeCopy((const SOperatorNode*)pNode, (SOperatorNode*)pDst); + case QUERY_NODE_LOGIC_CONDITION: + return logicConditionNodeCopy((const SLogicConditionNode*)pNode, (SLogicConditionNode*)pDst); + case QUERY_NODE_FUNCTION: + return functionNodeCopy((const SFunctionNode*)pNode, (SFunctionNode*)pDst); + case QUERY_NODE_REAL_TABLE: + case QUERY_NODE_TEMP_TABLE: + case QUERY_NODE_JOIN_TABLE: + case QUERY_NODE_GROUPING_SET: + case QUERY_NODE_ORDER_BY_EXPR: + case QUERY_NODE_LIMIT: + default: + break; + } + return pDst; +} + +SNodeList* nodesCloneList(const SNodeList* pList) { + SNodeList* pDst = nodesMakeList(); + if (NULL == pDst) { + return NULL; + } + SNode* pNode; + FOREACH(pNode, pList) { + SNode* pNewNode = nodesCloneNode(pNode); + if (NULL == pNewNode) { + nodesDestroyList(pDst); + return NULL; + } + nodesListAppend(pDst, pNewNode); + } + return pDst; } diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 959e10fb82..ad83bdbd19 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -21,7 +21,6 @@ int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen) { case QUERY_NODE_VALUE: case QUERY_NODE_OPERATOR: case QUERY_NODE_LOGIC_CONDITION: - case QUERY_NODE_IS_NULL_CONDITION: case QUERY_NODE_FUNCTION: case QUERY_NODE_REAL_TABLE: case QUERY_NODE_TEMP_TABLE: diff --git a/source/libs/nodes/src/nodesEqualFuncs.c b/source/libs/nodes/src/nodesEqualFuncs.c index 65eb6e9b32..fb2463d350 100644 --- a/source/libs/nodes/src/nodesEqualFuncs.c +++ b/source/libs/nodes/src/nodesEqualFuncs.c @@ -89,12 +89,6 @@ static bool logicConditionNodeEqual(const SLogicConditionNode* a, const SLogicCo return true; } -static bool isNullConditionNodeEqual(const SIsNullCondNode* a, const SIsNullCondNode* b) { - COMPARE_NODE_FIELD(pExpr); - COMPARE_SCALAR_FIELD(isNull); - return true; -} - static bool functionNodeEqual(const SFunctionNode* a, const SFunctionNode* b) { COMPARE_SCALAR_FIELD(funcId); COMPARE_NODE_LIST_FIELD(pParameterList); @@ -123,8 +117,6 @@ bool nodesEqualNode(const SNode* a, const SNode* b) { return operatorNodeEqual((const SOperatorNode*)a, (const SOperatorNode*)b); case QUERY_NODE_LOGIC_CONDITION: return logicConditionNodeEqual((const SLogicConditionNode*)a, (const SLogicConditionNode*)b); - case QUERY_NODE_IS_NULL_CONDITION: - return isNullConditionNodeEqual((const SIsNullCondNode*)a, (const SIsNullCondNode*)b); case QUERY_NODE_FUNCTION: return functionNodeEqual((const SFunctionNode*)a, (const SFunctionNode*)b); case QUERY_NODE_REAL_TABLE: diff --git a/source/libs/nodes/src/nodesTraverseFuncs.c b/source/libs/nodes/src/nodesTraverseFuncs.c index d1ded390db..b7e7ad6f0b 100644 --- a/source/libs/nodes/src/nodesTraverseFuncs.c +++ b/source/libs/nodes/src/nodesTraverseFuncs.c @@ -53,9 +53,6 @@ static EDealRes walkNode(SNode* pNode, ETraversalOrder order, FNodeWalker walker case QUERY_NODE_LOGIC_CONDITION: res = walkList(((SLogicConditionNode*)pNode)->pParameterList, order, walker, pContext); break; - case QUERY_NODE_IS_NULL_CONDITION: - res = walkNode(((SIsNullCondNode*)pNode)->pExpr, order, walker, pContext); - break; case QUERY_NODE_FUNCTION: res = walkList(((SFunctionNode*)pNode)->pParameterList, order, walker, pContext); break; @@ -179,9 +176,6 @@ static EDealRes rewriteNode(SNode** pRawNode, ETraversalOrder order, FNodeRewrit case QUERY_NODE_LOGIC_CONDITION: res = rewriteList(((SLogicConditionNode*)pNode)->pParameterList, order, rewriter, pContext); break; - case QUERY_NODE_IS_NULL_CONDITION: - res = rewriteNode(&(((SIsNullCondNode*)pNode)->pExpr), order, rewriter, pContext); - break; case QUERY_NODE_FUNCTION: res = rewriteList(((SFunctionNode*)pNode)->pParameterList, order, rewriter, pContext); break; diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 5d4ddd0e03..d94ef4d378 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -36,8 +36,6 @@ SNode* nodesMakeNode(ENodeType type) { return makeNode(type, sizeof(SOperatorNode)); case QUERY_NODE_LOGIC_CONDITION: return makeNode(type, sizeof(SLogicConditionNode)); - case QUERY_NODE_IS_NULL_CONDITION: - return makeNode(type, sizeof(SIsNullCondNode)); case QUERY_NODE_FUNCTION: return makeNode(type, sizeof(SFunctionNode)); case QUERY_NODE_REAL_TABLE: diff --git a/source/libs/parser/inc/astCreateFuncs.h b/source/libs/parser/inc/astCreateFuncs.h index 43bc5349e4..b44e621704 100644 --- a/source/libs/parser/inc/astCreateFuncs.h +++ b/source/libs/parser/inc/astCreateFuncs.h @@ -43,7 +43,6 @@ SNode* createLogicConditionNode(SAstCreateContext* pCxt, ELogicConditionType typ SNode* createOperatorNode(SAstCreateContext* pCxt, EOperatorType type, SNode* pLeft, SNode* pRight); SNode* createBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight); SNode* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight); -SNode* createIsNullCondNode(SAstCreateContext* pCxt, SNode* pExpr, bool isNull); SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList); SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList); SNode* createRealTableNode(SAstCreateContext* pCxt, const SToken* pDbName, const SToken* pTableName, const SToken* pTableAlias); diff --git a/source/libs/parser/inc/new_sql.y b/source/libs/parser/inc/new_sql.y index c4668a0f9d..065cb95650 100644 --- a/source/libs/parser/inc/new_sql.y +++ b/source/libs/parser/inc/new_sql.y @@ -192,12 +192,12 @@ predicate(A) ::= expression(B) NOT BETWEEN expression(C) AND expression(D). predicate(A) ::= expression(B) IS NULL(C). { PARSER_TRACE; SToken s = getTokenFromRawExprNode(pCxt, B); - A = createRawExprNodeExt(pCxt, &s, &C, createIsNullCondNode(pCxt, releaseRawExprNode(pCxt, B), true)); + A = createRawExprNodeExt(pCxt, &s, &C, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, B), NULL)); } predicate(A) ::= expression(B) IS NOT NULL(C). { PARSER_TRACE; SToken s = getTokenFromRawExprNode(pCxt, B); - A = createRawExprNodeExt(pCxt, &s, &C, createIsNullCondNode(pCxt, releaseRawExprNode(pCxt, B), false)); + A = createRawExprNodeExt(pCxt, &s, &C, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, B), NULL)); } predicate(A) ::= expression(B) in_op(C) in_predicate_value(D). { PARSER_TRACE; diff --git a/source/libs/parser/inc/parserImpl.h b/source/libs/parser/inc/parserImpl.h index b55060def7..4f6f0cf387 100644 --- a/source/libs/parser/inc/parserImpl.h +++ b/source/libs/parser/inc/parserImpl.h @@ -13,9 +13,6 @@ * along with this program. If not, see . */ -#include "querynodes.h" -#include "parser.h" - #ifndef _TD_AST_CREATE_FUNCS_H_ #define _TD_AST_CREATE_FUNCS_H_ @@ -23,9 +20,19 @@ extern "C" { #endif +#include "querynodes.h" +#include "parser.h" + +typedef enum EStmtType { + STMT_TYPE_CMD = 1, + STMT_TYPE_QUERY +} EStmtType; + typedef struct SQuery { + EStmtType stmtType; SNode* pRoot; - // todo reslut meta + int32_t numOfResCols; + SSchema* pResSchema; } SQuery; int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery); diff --git a/source/libs/parser/src/astCreateFuncs.c b/source/libs/parser/src/astCreateFuncs.c index ce2903f6aa..2615aca7f3 100644 --- a/source/libs/parser/src/astCreateFuncs.c +++ b/source/libs/parser/src/astCreateFuncs.c @@ -84,6 +84,10 @@ SNode* releaseRawExprNode(SAstCreateContext* pCxt, SNode* pNode) { } SToken getTokenFromRawExprNode(SAstCreateContext* pCxt, SNode* pNode) { + if (NULL == pNode || QUERY_NODE_RAW_EXPR != nodeType(pNode)) { + pCxt->valid = false; + return nil_token; + } SRawExprNode* target = (SRawExprNode*)pNode; SToken t = { .type = 0, .z = target->p, .n = target->n}; return t; @@ -166,14 +170,6 @@ SNode* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, createOperatorNode(pCxt, OP_TYPE_LOWER_THAN, pExpr, pLeft), createOperatorNode(pCxt, OP_TYPE_GREATER_THAN, pExpr, pRight)); } -SNode* createIsNullCondNode(SAstCreateContext* pCxt, SNode* pExpr, bool isNull) { - SIsNullCondNode* cond = (SIsNullCondNode*)nodesMakeNode(QUERY_NODE_IS_NULL_CONDITION); - CHECK_OUT_OF_MEM(cond); - cond->pExpr = pExpr; - cond->isNull = isNull; - return (SNode*)cond; -} - SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList) { SFunctionNode* func = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION); CHECK_OUT_OF_MEM(func); @@ -292,7 +288,11 @@ SNode* createGroupingSetNode(SAstCreateContext* pCxt, SNode* pNode) { } SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias) { - strncpy(((SExprNode*)pNode)->aliasName, pAlias->z, pAlias->n); + if (NULL == pNode || !pCxt->valid) { + return pNode; + } + uint32_t maxLen = sizeof(((SExprNode*)pNode)->aliasName); + strncpy(((SExprNode*)pNode)->aliasName, pAlias->z, pAlias->n > maxLen ? maxLen : pAlias->n); return pNode; } diff --git a/source/libs/parser/src/new_sql.c b/source/libs/parser/src/new_sql.c index 2b24448856..2d0c4b7eba 100644 --- a/source/libs/parser/src/new_sql.c +++ b/source/libs/parser/src/new_sql.c @@ -1717,7 +1717,7 @@ static YYACTIONTYPE yy_reduce( { PARSER_TRACE; SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy56); - yylhsminor.yy56 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createIsNullCondNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy56), true)); + yylhsminor.yy56 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy56), NULL)); } yymsp[-2].minor.yy56 = yylhsminor.yy56; break; @@ -1725,7 +1725,7 @@ static YYACTIONTYPE yy_reduce( { PARSER_TRACE; SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy56); - yylhsminor.yy56 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createIsNullCondNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy56), false)); + yylhsminor.yy56 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy56), NULL)); } yymsp[-3].minor.yy56 = yylhsminor.yy56; break; diff --git a/source/libs/parser/src/parserImpl.c b/source/libs/parser/src/parserImpl.c index d503cadd40..a2602c42ee 100644 --- a/source/libs/parser/src/parserImpl.c +++ b/source/libs/parser/src/parserImpl.c @@ -174,6 +174,19 @@ static uint32_t getToken(const char* z, uint32_t* tokenId) { return n; } +static EStmtType getStmtType(const SNode* pRootNode) { + if (NULL == pRootNode) { + return STMT_TYPE_CMD; + } + switch (nodeType(pRootNode)) { + case QUERY_NODE_SELECT_STMT: + return STMT_TYPE_QUERY; + default: + break; + } + return STMT_TYPE_CMD; +} + int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) { SAstCreateContext cxt; createAstCreateContext(pParseCxt, &cxt); @@ -181,15 +194,12 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) { int32_t i = 0; while (1) { SToken t0 = {0}; - // printf("===========================\n"); if (cxt.pQueryCxt->pSql[i] == 0) { NewParse(pParser, 0, t0, &cxt); goto abort_parse; } - // printf("input: [%s]\n", cxt.pQueryCxt->pSql + i); t0.n = getToken((char *)&cxt.pQueryCxt->pSql[i], &t0.type); t0.z = (char *)(cxt.pQueryCxt->pSql + i); - // printf("token : %d %d [%s]\n", t0.type, t0.n, t0.z); i += t0.n; switch (t0.type) { @@ -201,14 +211,12 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) { NewParse(pParser, 0, t0, &cxt); goto abort_parse; } - case TK_QUESTION: case TK_ILLEGAL: { snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unrecognized token: \"%s\"", t0.z); cxt.valid = false; goto abort_parse; } - case TK_HEX: case TK_OCT: case TK_BIN: { @@ -216,7 +224,6 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) { cxt.valid = false; goto abort_parse; } - default: NewParse(pParser, t0.type, t0, &cxt); // NewParseTrace(stdout, ""); @@ -227,9 +234,9 @@ int32_t doParse(SParseContext* pParseCxt, SQuery* pQuery) { } abort_parse: - // printf("doParse completed.\n"); NewParseFree(pParser, free); destroyAstCreateContext(&cxt); + pQuery->stmtType = getStmtType(cxt.pRootNode); pQuery->pRoot = cxt.pRootNode; return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED; } @@ -255,7 +262,6 @@ static bool beforeHaving(ESqlClause clause) { typedef struct STranslateContext { SParseContext* pParseCxt; - FuncMgtHandle fmgt; int32_t errCode; SMsgBuf msgBuf; SArray* pNsLevel; // element is SArray*, the element of this subarray is STableNode* @@ -292,6 +298,8 @@ static char* getSyntaxErrFormat(int32_t errCode) { return "Not SELECTed expression"; case TSDB_CODE_PAR_NOT_SINGLE_GROUP: return "Not a single-group group function"; + case TSDB_CODE_PAR_OUT_OF_MEMORY: + return "Out of memory"; default: return "Unknown error"; } @@ -376,12 +384,15 @@ static void setColumnInfoByExpr(const STableNode* pTable, SExprNode* pExpr, SCol pCol->node.resType = pExpr->resType; } -static int32_t createColumnNodeByTable(const STableNode* pTable, SNodeList* pList) { +static int32_t createColumnNodeByTable(STranslateContext* pCxt, const STableNode* pTable, SNodeList* pList) { if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) { const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta; int32_t nums = pMeta->tableInfo.numOfTags + pMeta->tableInfo.numOfColumns; for (int32_t i = 0; i < nums; ++i) { SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); + if (NULL == pCol) { + return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY); + } setColumnInfoBySchema(pTable, pMeta->schema + i, pCol); nodesListAppend(pList, (SNode*)pCol); } @@ -390,10 +401,14 @@ static int32_t createColumnNodeByTable(const STableNode* pTable, SNodeList* pLis SNode* pNode; FOREACH(pNode, pProjectList) { SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); + if (NULL == pCol) { + return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY); + } setColumnInfoByExpr(pTable, (SExprNode*)pNode, pCol); nodesListAppend(pList, (SNode*)pCol); } } + return TSDB_CODE_SUCCESS; } static bool findAndSetColumn(SColumnNode* pCol, const STableNode* pTable) { @@ -539,7 +554,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) { case TSDB_DATA_TYPE_UTINYINT: case TSDB_DATA_TYPE_USMALLINT: case TSDB_DATA_TYPE_UINT: - case TSDB_DATA_TYPE_UBIGINT:{ + case TSDB_DATA_TYPE_UBIGINT: { char* endPtr = NULL; pVal->datum.u = strtoull(pVal->literal, &endPtr, 10); break; @@ -556,12 +571,20 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) { case TSDB_DATA_TYPE_VARBINARY: { int32_t n = strlen(pVal->literal); pVal->datum.p = calloc(1, n); + if (NULL == pVal->datum.p) { + generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY); + return DEAL_RES_ERROR; + } trimStringCopy(pVal->literal, n, pVal->datum.p); break; } case TSDB_DATA_TYPE_TIMESTAMP: { int32_t n = strlen(pVal->literal); char* tmp = calloc(1, n); + if (NULL == tmp) { + generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY); + return DEAL_RES_ERROR; + } int32_t len = trimStringCopy(pVal->literal, n, tmp); if (taosParseTime(tmp, &pVal->datum.i, len, pVal->node.resType.precision, tsDaylight) != TSDB_CODE_SUCCESS) { tfree(tmp); @@ -608,7 +631,7 @@ static EDealRes translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) { } static EDealRes translateFunction(STranslateContext* pCxt, SFunctionNode* pFunc) { - if (TSDB_CODE_SUCCESS != fmGetFuncInfo(pCxt->fmgt, pFunc->functionName, &pFunc->funcId, &pFunc->funcType)) { + if (TSDB_CODE_SUCCESS != fmGetFuncInfo(pFunc->functionName, &pFunc->funcId, &pFunc->funcType)) { generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_INVALID_FUNTION, pFunc->functionName); return DEAL_RES_ERROR; } @@ -806,9 +829,15 @@ static int32_t translateStar(STranslateContext* pCxt, SSelectStmt* pSelect, bool SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel); size_t nums = taosArrayGetSize(pTables); pSelect->pProjectionList = nodesMakeList(); + if (NULL == pSelect->pProjectionList) { + return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY); + } for (size_t i = 0; i < nums; ++i) { STableNode* pTable = taosArrayGetP(pTables, i); - createColumnNodeByTable(pTable, pSelect->pProjectionList); + int32_t code = createColumnNodeByTable(pCxt, pTable, pSelect->pProjectionList); + if (TSDB_CODE_SUCCESS != code) { + return code; + } } *pIsSelectStar = true; } else { @@ -848,7 +877,7 @@ static int32_t getPositionValue(const SValueNode* pVal) { return -1; } -static bool translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjectionList, SNodeList* pOrderByList, bool* pOther) { +static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjectionList, SNodeList* pOrderByList, bool* pOther) { *pOther = false; SNode* pNode; FOREACH(pNode, pOrderByList) { @@ -856,18 +885,20 @@ static bool translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjec if (QUERY_NODE_VALUE == nodeType(pExpr)) { SValueNode* pVal = (SValueNode*)pExpr; if (!translateValue(pCxt, pVal)) { - return false; + return pCxt->errCode; } - int32_t pos = getPositionValue((SValueNode*)pExpr); + int32_t pos = getPositionValue(pVal); if (pos < 0) { ERASE_NODE(pOrderByList); nodesDestroyNode(pNode); continue; } else if (0 == pos || pos > LIST_LENGTH(pProjectionList)) { - generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT); - return false; + return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT); } else { SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); + if (NULL == pCol) { + return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY); + } setColumnInfoByExpr(NULL, (SExprNode*)nodesListGetNode(pProjectionList, pos - 1), pCol); ((SOrderByExprNode*)pNode)->pExpr = (SNode*)pCol; nodesDestroyNode(pExpr); @@ -876,19 +907,20 @@ static bool translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjec *pOther = true; } } - return true; + return TSDB_CODE_SUCCESS; } static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) { bool other; - if (!translateOrderByPosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other)) { - return pCxt->errCode; + int32_t code = translateOrderByPosition(pCxt, pSelect->pProjectionList, pSelect->pOrderByList, &other); + if (TSDB_CODE_SUCCESS != code) { + return code; } if (!other) { return TSDB_CODE_SUCCESS; } pCxt->currClause = SQL_CLAUSE_ORDER_BY; - int32_t code = translateExprList(pCxt, pSelect->pOrderByList); + code = translateExprList(pCxt, pSelect->pOrderByList); if (TSDB_CODE_SUCCESS == code) { code = checkExprListForGroupBy(pCxt, pSelect->pOrderByList); } @@ -945,12 +977,6 @@ static int32_t translateFrom(STranslateContext* pCxt, SNode* pTable) { return translateTable(pCxt, pTable); } -// typedef struct SSelectStmt { -// bool isDistinct; -// SNode* pLimit; -// SNode* pSlimit; -// } SSelectStmt; - static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) { pCxt->pCurrStmt = pSelect; int32_t code = translateFrom(pCxt, pSelect->pFromTable); @@ -1004,6 +1030,26 @@ static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode) { return code; } +int32_t setReslutSchema(STranslateContext* pCxt, SQuery* pQuery) { + if (QUERY_NODE_SELECT_STMT == nodeType(pQuery->pRoot)) { + SSelectStmt* pSelect = (SSelectStmt*)pQuery->pRoot; + pQuery->numOfResCols = LIST_LENGTH(pSelect->pProjectionList); + pQuery->pResSchema = calloc(pQuery->numOfResCols, sizeof(SSchema)); + if (NULL == pQuery->pResSchema) { + return generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_OUT_OF_MEMORY); + } + SNode* pNode; + int32_t index = 0; + FOREACH(pNode, pSelect->pProjectionList) { + SExprNode* pExpr = (SExprNode*)pNode; + pQuery->pResSchema[index].type = pExpr->resType.type; + pQuery->pResSchema[index].bytes = pExpr->resType.bytes; + strcpy(pQuery->pResSchema[index].name, pExpr->aliasName); + } + } + return TSDB_CODE_SUCCESS; +} + int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) { STranslateContext cxt = { .pParseCxt = pParseCxt, @@ -1014,12 +1060,11 @@ int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) { .currClause = 0 }; int32_t code = fmFuncMgtInit(); - if (TSDB_CODE_SUCCESS != code) { - return code; + if (TSDB_CODE_SUCCESS == code) { + code = translateQuery(&cxt, pQuery->pRoot); } - code = fmGetHandle(&cxt.fmgt); - if (TSDB_CODE_SUCCESS != code) { - return code; + if (TSDB_CODE_SUCCESS == code && STMT_TYPE_QUERY == pQuery->stmtType) { + code = setReslutSchema(&cxt, pQuery); } - return translateQuery(&cxt, pQuery->pRoot); + return code; } diff --git a/source/libs/planner/CMakeLists.txt b/source/libs/planner/CMakeLists.txt index 8d8c148fde..14b4488e6a 100644 --- a/source/libs/planner/CMakeLists.txt +++ b/source/libs/planner/CMakeLists.txt @@ -8,7 +8,7 @@ target_include_directories( target_link_libraries( planner - PRIVATE os util catalog cjson parser function qcom + PRIVATE os util nodes catalog cjson parser function qcom PUBLIC transport ) diff --git a/source/libs/planner/inc/plannerImpl.h b/source/libs/planner/inc/plannerImpl.h index 050329693c..1f8df990b1 100644 --- a/source/libs/planner/inc/plannerImpl.h +++ b/source/libs/planner/inc/plannerImpl.h @@ -20,6 +20,33 @@ extern "C" { #endif +#include "querynodes.h" +#include "planner.h" + +typedef struct SLogicNode { + ENodeType type; + SNodeList* pTargets; + SNode* pConditions; + SNodeList* pChildren; + struct SLogicNode* pParent; +} SLogicNode; + +typedef struct SScanLogicNode { + SLogicNode node; + SNodeList* pScanCols; + struct STableMeta* pMeta; +} SScanLogicNode; + +typedef struct SFilterLogicNode { + SLogicNode node; +} SFilterLogicNode; + +typedef struct SAggLogicNode { + SLogicNode node; + SNodeList* pGroupKeys; + SNodeList* pAggFuncs; +} SAggLogicNode; + #ifdef __cplusplus } #endif diff --git a/source/libs/planner/src/plannerImpl.c b/source/libs/planner/src/plannerImpl.c index 6acb927db9..ddb3023bb3 100644 --- a/source/libs/planner/src/plannerImpl.c +++ b/source/libs/planner/src/plannerImpl.c @@ -13,7 +13,192 @@ * along with this program. If not, see . */ +#include "plannerImpl.h" +#include "functionMgt.h" -// int32_t getPlan(SNode* pRoot, SQueryPlanNode** pQueryPlan) { +static SLogicNode* createQueryLogicNode(SNode* pStmt); -// } \ No newline at end of file +typedef struct SCollectColumnsCxt { + SNodeList* pCols; + SHashObj* pColIdHash; +} SCollectColumnsCxt; + +static EDealRes doCollectColumns(SNode* pNode, void* pContext) { + if (QUERY_NODE_COLUMN == nodeType(pNode)) { + SCollectColumnsCxt* pCxt = (SCollectColumnsCxt*)pContext; + int16_t colId = ((SColumnNode*)pNode)->colId; + if (colId > 0) { + if (NULL == taosHashGet(pCxt->pColIdHash, &colId, sizeof(colId))) { + taosHashPut(pCxt->pColIdHash, &colId, sizeof(colId), NULL, 0); + nodesListAppend(pCxt->pCols, pNode); + } + } + } + return DEAL_RES_CONTINUE; +} + +static SNodeList* collectColumns(SSelectStmt* pSelect) { + SCollectColumnsCxt cxt = { .pCols = nodesMakeList(), .pColIdHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK) }; + if (NULL == cxt.pCols || NULL == cxt.pColIdHash) { + return NULL; + } + nodesWalkNode(pSelect->pFromTable, doCollectColumns, &cxt); + nodesWalkNode(pSelect->pWhere, doCollectColumns, &cxt); + nodesWalkList(pSelect->pPartitionByList, doCollectColumns, &cxt); + nodesWalkNode(pSelect->pWindow, doCollectColumns, &cxt); + nodesWalkList(pSelect->pGroupByList, doCollectColumns, &cxt); + nodesWalkNode(pSelect->pHaving, doCollectColumns, &cxt); + nodesWalkList(pSelect->pProjectionList, doCollectColumns, &cxt); + nodesWalkList(pSelect->pOrderByList, doCollectColumns, &cxt); + taosHashCleanup(cxt.pColIdHash); + return cxt.pCols; +} + +typedef struct SCollectAggFuncsCxt { + SNodeList* pAggFuncs; +} SCollectAggFuncsCxt; + +static EDealRes doCollectAggFuncs(SNode* pNode, void* pContext) { + if (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsAggFunc(((SFunctionNode*)pNode)->funcId)) { + SCollectAggFuncsCxt* pCxt = (SCollectAggFuncsCxt*)pContext; + nodesListAppend(pCxt->pAggFuncs, pNode); + return DEAL_RES_IGNORE_CHILD; + } + return DEAL_RES_CONTINUE; +} + +static SNodeList* collectAggFuncs(SSelectStmt* pSelect) { + SCollectAggFuncsCxt cxt = { .pAggFuncs = nodesMakeList() }; + if (NULL == cxt.pAggFuncs) { + return NULL; + } + nodesWalkNode(pSelect->pHaving, doCollectAggFuncs, &cxt); + nodesWalkList(pSelect->pProjectionList, doCollectAggFuncs, &cxt); + if (!pSelect->isDistinct) { + nodesWalkList(pSelect->pOrderByList, doCollectAggFuncs, &cxt); + } + return cxt.pAggFuncs; +} + +typedef struct SRewriteExprCxt { + SNodeList* pTargets; +} SRewriteExprCxt; + +static EDealRes doRewriteExpr(SNode** pNode, void* pContext) { + SRewriteExprCxt* pCxt = (SRewriteExprCxt*)pContext; + SNode* pTarget; + int32_t index = 0; + FOREACH(pTarget, pCxt->pTargets) { + if (nodesEqualNode(pTarget, *pNode)) { + nodesDestroyNode(*pNode); + *pNode = nodesMakeNode(QUERY_NODE_COLUMN_REF); + ((SColumnRef*)*pNode)->slotId = index; + return DEAL_RES_IGNORE_CHILD; + } + ++index; + } + return DEAL_RES_CONTINUE; +} + +static int32_t rewriteExpr(SNodeList* pTargets, SSelectStmt* pSelect) { + SRewriteExprCxt cxt = { .pTargets = pTargets }; + nodesRewriteNode(&(pSelect->pFromTable), doRewriteExpr, &cxt); + nodesRewriteNode(&(pSelect->pWhere), doRewriteExpr, &cxt); + nodesRewriteList(pSelect->pPartitionByList, doRewriteExpr, &cxt); + nodesRewriteNode(&(pSelect->pWindow), doRewriteExpr, &cxt); + nodesRewriteList(pSelect->pGroupByList, doRewriteExpr, &cxt); + nodesRewriteNode(&(pSelect->pHaving), doRewriteExpr, &cxt); + nodesRewriteList(pSelect->pProjectionList, doRewriteExpr, &cxt); + nodesRewriteList(pSelect->pOrderByList, doRewriteExpr, &cxt); + return TSDB_CODE_SUCCESS; +} + +static SLogicNode* pushLogicNode(SLogicNode* pRoot, SLogicNode* pNode) { + if (NULL == pRoot) { + return pNode; + } + if (NULL == pNode) { + return pRoot; + } + pRoot->pParent = pNode; + if (NULL == pNode->pChildren) { + pNode->pChildren = nodesMakeList(); + } + nodesListAppend(pNode->pChildren, (SNode*)pRoot); + return pNode; +} + +static SNodeList* createScanTargets(SNodeList* pCols) { + +} + +static SLogicNode* createScanLogicNode(SSelectStmt* pSelect, SRealTableNode* pRealTable) { + SScanLogicNode* pScan = (SScanLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_SCAN); + SNodeList* pCols = collectColumns(pSelect); + pScan->pScanCols = nodesCloneList(pCols); + // + rewriteExpr(pScan->pScanCols, pSelect); + pScan->node.pTargets = createScanTargets(pCols); + pScan->pMeta = pRealTable->pMeta; + return (SLogicNode*)pScan; +} + +static SLogicNode* createSubqueryLogicNode(SSelectStmt* pSelect, STempTableNode* pTable) { + return createQueryLogicNode(pTable->pSubquery); +} + +static SLogicNode* createLogicNodeByTable(SSelectStmt* pSelect, SNode* pTable) { + switch (nodeType(pTable)) { + case QUERY_NODE_REAL_TABLE: + return createScanLogicNode(pSelect, (SRealTableNode*)pTable); + case QUERY_NODE_TEMP_TABLE: + return createSubqueryLogicNode(pSelect, (STempTableNode*)pTable); + case QUERY_NODE_JOIN_TABLE: + default: + break; + } + return NULL; +} + +static SLogicNode* createFilterLogicNode(SNode* pWhere) { + if (NULL == pWhere) { + return NULL; + } + SFilterLogicNode* pFilter = (SFilterLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_FILTER); + pFilter->node.pConditions = nodesCloneNode(pWhere); + return (SLogicNode*)pFilter; +} + +static SLogicNode* createAggLogicNode(SSelectStmt* pSelect, SNodeList* pGroupByList, SNode* pHaving) { + SNodeList* pAggFuncs = collectAggFuncs(pSelect); + if (NULL == pAggFuncs && NULL == pGroupByList) { + return NULL; + } + SAggLogicNode* pAgg = (SAggLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG); + pAgg->pGroupKeys = nodesCloneList(pGroupByList); + pAgg->pAggFuncs = nodesCloneList(pAggFuncs); + pAgg->node.pConditions = nodesCloneNode(pHaving); + return (SLogicNode*)pAgg; +} + +static SLogicNode* createSelectLogicNode(SSelectStmt* pSelect) { + SLogicNode* pRoot = createLogicNodeByTable(pSelect, pSelect->pFromTable); + pRoot = pushLogicNode(pRoot, createFilterLogicNode(pSelect->pWhere)); + pRoot = pushLogicNode(pRoot, createAggLogicNode(pSelect, pSelect->pGroupByList, pSelect->pHaving)); + // pRoot = pushLogicNode(pRoot, createProjectLogicNode(pSelect, pSelect->pProjectionList)); + return pRoot; +} + +static SLogicNode* createQueryLogicNode(SNode* pStmt) { + switch (nodeType(pStmt)) { + case QUERY_NODE_SELECT_STMT: + return createSelectLogicNode((SSelectStmt*)pStmt); + default: + break; + } +} + +int32_t createLogicPlan(SNode* pNode, SLogicNode** pLogicNode) { + *pLogicNode = createQueryLogicNode(pNode); + return TSDB_CODE_SUCCESS; +} From 83479b08782881e792d08a9222e61f971675673d Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Fri, 11 Feb 2022 09:26:55 -0500 Subject: [PATCH 2/2] TD-13495 planner refactoring --- include/libs/nodes/querynodes.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index 8a89a4fb6d..ea9653e4a8 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -85,6 +85,10 @@ typedef enum EOperatorType { OP_TYPE_DIV, OP_TYPE_MOD, + // bit operator + OP_TYPE_BIT_AND, + OP_TYPE_BIT_OR, + // comparison operator OP_TYPE_GREATER_THAN, OP_TYPE_GREATER_EQUAL,