feat: support partition by expression and aggregate function output together
This commit is contained in:
parent
b857d390e7
commit
fb1e845256
|
@ -1450,6 +1450,25 @@ static int32_t rewriteColsToSelectValFunc(STranslateContext* pCxt, SSelectStmt*
|
||||||
return pCxt->errCode;
|
return pCxt->errCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static EDealRes rewriteExprsToGroupKeyFuncImpl(SNode** pNode, void* pContext) {
|
||||||
|
STranslateContext* pCxt = pContext;
|
||||||
|
SNode* pPartKey = NULL;
|
||||||
|
FOREACH(pPartKey, pCxt->pCurrSelectStmt->pPartitionByList) {
|
||||||
|
if (nodesEqualNode(pPartKey, *pNode)) {
|
||||||
|
return rewriteExprToGroupKeyFunc(pCxt, pNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DEAL_RES_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t rewriteExprsToGroupKeyFunc(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
|
nodesRewriteExprs(pSelect->pProjectionList, rewriteExprsToGroupKeyFuncImpl, pCxt);
|
||||||
|
if (TSDB_CODE_SUCCESS == pCxt->errCode && !pSelect->isDistinct) {
|
||||||
|
nodesRewriteExprs(pSelect->pOrderByList, rewriteExprsToGroupKeyFuncImpl, pCxt);
|
||||||
|
}
|
||||||
|
return pCxt->errCode;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct CheckAggColCoexistCxt {
|
typedef struct CheckAggColCoexistCxt {
|
||||||
STranslateContext* pTranslateCxt;
|
STranslateContext* pTranslateCxt;
|
||||||
bool existAggFunc;
|
bool existAggFunc;
|
||||||
|
@ -1459,28 +1478,28 @@ typedef struct CheckAggColCoexistCxt {
|
||||||
bool existOtherAggFunc;
|
bool existOtherAggFunc;
|
||||||
} CheckAggColCoexistCxt;
|
} CheckAggColCoexistCxt;
|
||||||
|
|
||||||
static EDealRes doCheckAggColCoexist(SNode** pNode, void* pContext) {
|
static EDealRes doCheckAggColCoexist(SNode* pNode, void* pContext) {
|
||||||
CheckAggColCoexistCxt* pCxt = (CheckAggColCoexistCxt*)pContext;
|
CheckAggColCoexistCxt* pCxt = (CheckAggColCoexistCxt*)pContext;
|
||||||
if (isSelectFunc(*pNode)) {
|
if (isSelectFunc(pNode)) {
|
||||||
++(pCxt->selectFuncNum);
|
++(pCxt->selectFuncNum);
|
||||||
} else if (isAggFunc(*pNode)) {
|
} else if (isAggFunc(pNode)) {
|
||||||
pCxt->existOtherAggFunc = true;
|
pCxt->existOtherAggFunc = true;
|
||||||
}
|
}
|
||||||
if (isAggFunc(*pNode)) {
|
if (isAggFunc(pNode)) {
|
||||||
pCxt->existAggFunc = true;
|
pCxt->existAggFunc = true;
|
||||||
return DEAL_RES_IGNORE_CHILD;
|
return DEAL_RES_IGNORE_CHILD;
|
||||||
}
|
}
|
||||||
if (isIndefiniteRowsFunc(*pNode)) {
|
if (isIndefiniteRowsFunc(pNode)) {
|
||||||
pCxt->existIndefiniteRowsFunc = true;
|
pCxt->existIndefiniteRowsFunc = true;
|
||||||
return DEAL_RES_IGNORE_CHILD;
|
return DEAL_RES_IGNORE_CHILD;
|
||||||
}
|
}
|
||||||
SNode* pPartKey = NULL;
|
SNode* pPartKey = NULL;
|
||||||
FOREACH(pPartKey, pCxt->pTranslateCxt->pCurrSelectStmt->pPartitionByList) {
|
FOREACH(pPartKey, pCxt->pTranslateCxt->pCurrSelectStmt->pPartitionByList) {
|
||||||
if (nodesEqualNode(pPartKey, *pNode)) {
|
if (nodesEqualNode(pPartKey, pNode)) {
|
||||||
return rewriteExprToGroupKeyFunc(pCxt->pTranslateCxt, pNode);
|
return DEAL_RES_IGNORE_CHILD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isScanPseudoColumnFunc(*pNode) || QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
if (isScanPseudoColumnFunc(pNode) || QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||||
pCxt->existCol = true;
|
pCxt->existCol = true;
|
||||||
}
|
}
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
|
@ -1496,9 +1515,9 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
||||||
.existIndefiniteRowsFunc = false,
|
.existIndefiniteRowsFunc = false,
|
||||||
.selectFuncNum = 0,
|
.selectFuncNum = 0,
|
||||||
.existOtherAggFunc = false};
|
.existOtherAggFunc = false};
|
||||||
nodesRewriteExprs(pSelect->pProjectionList, doCheckAggColCoexist, &cxt);
|
nodesWalkExprs(pSelect->pProjectionList, doCheckAggColCoexist, &cxt);
|
||||||
if (!pSelect->isDistinct) {
|
if (!pSelect->isDistinct) {
|
||||||
nodesRewriteExprs(pSelect->pOrderByList, doCheckAggColCoexist, &cxt);
|
nodesWalkExprs(pSelect->pOrderByList, doCheckAggColCoexist, &cxt);
|
||||||
}
|
}
|
||||||
if (1 == cxt.selectFuncNum && !cxt.existOtherAggFunc) {
|
if (1 == cxt.selectFuncNum && !cxt.existOtherAggFunc) {
|
||||||
return rewriteColsToSelectValFunc(pCxt, pSelect);
|
return rewriteColsToSelectValFunc(pCxt, pSelect);
|
||||||
|
@ -1509,6 +1528,9 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
||||||
if (cxt.existIndefiniteRowsFunc && cxt.existCol) {
|
if (cxt.existIndefiniteRowsFunc && cxt.existCol) {
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
||||||
}
|
}
|
||||||
|
if (cxt.existAggFunc && NULL != pSelect->pPartitionByList) {
|
||||||
|
return rewriteExprsToGroupKeyFunc(pCxt, pSelect);
|
||||||
|
}
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1075,16 +1075,6 @@ static int32_t partTagsOptRebuildTbanme(SNodeList* pPartKeys) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t partTagOptRewriteGroupKey(SAggLogicNode* pAgg, SScanLogicNode* pScan) {
|
|
||||||
// SNode* pNode = NULL;
|
|
||||||
// FOREACH(pNode, pScan->pPartTags) {
|
|
||||||
// if (QUERY_NODE_COLUMN != nodeType(pNode)) {
|
|
||||||
// createColumnByRewriteExpr(pNode, );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||||
SLogicNode* pNode = optFindPossibleNode(pLogicSubplan->pNode, partTagsOptMayBeOptimized);
|
SLogicNode* pNode = optFindPossibleNode(pLogicSubplan->pNode, partTagsOptMayBeOptimized);
|
||||||
if (NULL == pNode) {
|
if (NULL == pNode) {
|
||||||
|
@ -1110,9 +1100,6 @@ static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NODES_DESTORY_LIST(((SAggLogicNode*)pNode)->pGroupKeys);
|
NODES_DESTORY_LIST(((SAggLogicNode*)pNode)->pGroupKeys);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = partTagOptRewriteGroupKey((SAggLogicNode*)pNode, pScan);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = partTagsOptRebuildTbanme(pScan->pPartTags);
|
code = partTagsOptRebuildTbanme(pScan->pPartTags);
|
||||||
|
@ -1202,7 +1189,7 @@ static const SOptimizeRule optimizeRuleSet[] = {
|
||||||
{.pName = "ConditionPushDown", .optimizeFunc = cpdOptimize},
|
{.pName = "ConditionPushDown", .optimizeFunc = cpdOptimize},
|
||||||
{.pName = "OrderByPrimaryKey", .optimizeFunc = opkOptimize},
|
{.pName = "OrderByPrimaryKey", .optimizeFunc = opkOptimize},
|
||||||
{.pName = "SmaIndex", .optimizeFunc = smaOptimize},
|
{.pName = "SmaIndex", .optimizeFunc = smaOptimize},
|
||||||
{.pName = "PartitionTags", .optimizeFunc = partTagsOptimize},
|
// {.pName = "PartitionTags", .optimizeFunc = partTagsOptimize},
|
||||||
{.pName = "EliminateProject", .optimizeFunc = eliminateProjOptimize}
|
{.pName = "EliminateProject", .optimizeFunc = eliminateProjOptimize}
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
Loading…
Reference in New Issue