From 8088b67dc905dc87da0479620b02890368c8acc8 Mon Sep 17 00:00:00 2001 From: slzhou Date: Mon, 27 Jun 2022 19:07:37 +0800 Subject: [PATCH 1/3] feat: add merge projects optimization --- source/libs/planner/src/planOptimizer.c | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index f1cad6010c..8420f40ec9 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -1235,6 +1235,45 @@ static int32_t eliminateSetOpOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLo return eliminateSetOpOptimizeImpl(pCxt, pLogicSubplan, pSetOpNode); } +//=================================================================================================================== +// merge projects +static bool mergeProjectsMayBeOptimized(SLogicNode* pNode) { + if (QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren)) { + return false; + } + SLogicNode *pChild = (SLogicNode*)nodesListGetNode(pNode->pChildren, 0); + if (QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(pChild) || 1 < LIST_LENGTH(pChild->pChildren) || + NULL != pChild->pConditions || NULL != pNode->pLimit || NULL != pNode->pSlimit) { + return false; + } + return true; +} + +typedef struct SMergeProjectionsContext { + +} SMergeProjectionsContext; + +static EDealRes mergeProjectionsExpr(SNode** pNode, void* pContext) { + return DEAL_RES_CONTINUE; +} + +static int32_t mergeProjectsOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, SLogicNode* pProjectNode) { + SProjectLogicNode* pProject = (SProjectLogicNode*)pProjectNode; + SProjectLogicNode* pChild = (SProjectLogicNode*)nodesListGetNode(pProjectNode->pChildren, 0); + SMergeProjectionsContext cxt = {}; + nodesRewriteExprs(pChild->pProjections, mergeProjectionsExpr, &cxt); + return TSDB_CODE_SUCCESS; +} + +static int32_t mergeProjectsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) { + SLogicNode* pProjectNode = optFindPossibleNode(pLogicSubplan->pNode, mergeProjectsMayBeOptimized); + if (NULL == pProjectNode) { + return TSDB_CODE_SUCCESS; + } + + return mergeProjectsOptimizeImpl(pCxt, pLogicSubplan, pProjectNode); +} + // clang-format off static const SOptimizeRule optimizeRuleSet[] = { {.pName = "OptimizeScanData", .optimizeFunc = osdOptimize}, @@ -1242,8 +1281,11 @@ static const SOptimizeRule optimizeRuleSet[] = { {.pName = "OrderByPrimaryKey", .optimizeFunc = opkOptimize}, {.pName = "SmaIndex", .optimizeFunc = smaOptimize}, {.pName = "PartitionTags", .optimizeFunc = partTagsOptimize}, + {.pName = "MergeProjects", .optimizeFunc = mergeProjectsOptimize}, {.pName = "EliminateProject", .optimizeFunc = eliminateProjOptimize}, {.pName = "EliminateSetOperator", .optimizeFunc = eliminateSetOpOptimize} + {.pName = "EliminateSetOperator", .optimizeFunc = eliminateSetOpOptimize}, + {.pName = "RewriteTail", .optimizeFunc = rewriteTailOptimize}, }; // clang-format on From f80af20d3b864fb5941b4a3e0f7c243c680115e0 Mon Sep 17 00:00:00 2001 From: slzhou Date: Tue, 28 Jun 2022 10:55:34 +0800 Subject: [PATCH 2/3] fix: add merge parent project and child project optimization --- source/libs/planner/src/planOptimizer.c | 48 ++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 9481c26d7a..eb0f02c92c 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -1375,19 +1375,57 @@ static bool mergeProjectsMayBeOptimized(SLogicNode* pNode) { } typedef struct SMergeProjectionsContext { - + SProjectLogicNode* pChildProj; + int32_t errCode; } SMergeProjectionsContext; static EDealRes mergeProjectionsExpr(SNode** pNode, void* pContext) { + SMergeProjectionsContext* pCxt = pContext; + SProjectLogicNode* pChildProj = pCxt->pChildProj; + if (QUERY_NODE_COLUMN == nodeType(*pNode)) { + SNode* pTarget; + FOREACH(pTarget, ((SLogicNode*)pChildProj)->pTargets) { + if (nodesEqualNode(pTarget, *pNode)) { + SNode* pProjection; + FOREACH(pProjection, pChildProj->pProjections) { + if (0 == strcmp(((SColumnNode*)pTarget)->colName, ((SExprNode*)pProjection)->aliasName)) { + SNode* pExpr = nodesCloneNode(pProjection); + if (pExpr == NULL) { + pCxt->errCode = terrno; + return DEAL_RES_ERROR; + } + nodesDestroyNode(*pNode); + *pNode = pExpr; + } + } + } + } + return DEAL_RES_IGNORE_CHILD; + } return DEAL_RES_CONTINUE; } static int32_t mergeProjectsOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, SLogicNode* pProjectNode) { SProjectLogicNode* pProject = (SProjectLogicNode*)pProjectNode; - SProjectLogicNode* pChild = (SProjectLogicNode*)nodesListGetNode(pProjectNode->pChildren, 0); - SMergeProjectionsContext cxt = {}; - nodesRewriteExprs(pChild->pProjections, mergeProjectionsExpr, &cxt); - return TSDB_CODE_SUCCESS; + SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pProjectNode->pChildren, 0); + SMergeProjectionsContext cxt = {.pChildProj = (SProjectLogicNode*)pChild}; + + nodesRewriteExprs(pProject->pProjections, mergeProjectionsExpr, &cxt); + int32_t code = cxt.errCode; + if (TSDB_CODE_SUCCESS == code) { + if (1 == LIST_LENGTH(pChild->pChildren)) { + SLogicNode* pGrandChild = (SLogicNode*)nodesListGetNode(pChild->pChildren, 0); + code = replaceLogicNode(pLogicSubplan, pChild, pGrandChild); + } else { // no grand child + NODES_CLEAR_LIST(pProjectNode->pChildren); + } + } + + if (TSDB_CODE_SUCCESS == code) { + NODES_CLEAR_LIST(pChild->pChildren); + } + nodesDestroyNode((SNode*)pChild); + return code; } static int32_t mergeProjectsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) { From 4110c0049739804159c6c66fff8b10c67598dd58 Mon Sep 17 00:00:00 2001 From: slzhou Date: Tue, 28 Jun 2022 11:58:39 +0800 Subject: [PATCH 3/3] fix: initialize errCode of SMergeProjectsContext --- source/libs/planner/src/planOptimizer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index eb0f02c92c..638e3f5604 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -1405,19 +1405,19 @@ static EDealRes mergeProjectionsExpr(SNode** pNode, void* pContext) { return DEAL_RES_CONTINUE; } -static int32_t mergeProjectsOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, SLogicNode* pProjectNode) { - SProjectLogicNode* pProject = (SProjectLogicNode*)pProjectNode; - SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pProjectNode->pChildren, 0); - SMergeProjectionsContext cxt = {.pChildProj = (SProjectLogicNode*)pChild}; +static int32_t mergeProjectsOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan, SLogicNode* pSelfNode) { + SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pSelfNode->pChildren, 0); + SMergeProjectionsContext cxt = {.pChildProj = (SProjectLogicNode*)pChild, .errCode = TSDB_CODE_SUCCESS}; - nodesRewriteExprs(pProject->pProjections, mergeProjectionsExpr, &cxt); + nodesRewriteExprs(((SProjectLogicNode*)pSelfNode)->pProjections, mergeProjectionsExpr, &cxt); int32_t code = cxt.errCode; + if (TSDB_CODE_SUCCESS == code) { if (1 == LIST_LENGTH(pChild->pChildren)) { SLogicNode* pGrandChild = (SLogicNode*)nodesListGetNode(pChild->pChildren, 0); code = replaceLogicNode(pLogicSubplan, pChild, pGrandChild); } else { // no grand child - NODES_CLEAR_LIST(pProjectNode->pChildren); + NODES_CLEAR_LIST(pSelfNode->pChildren); } }