feat: the having clause can be used after the partition by clause or window clause

This commit is contained in:
Xiaoyu Wang 2023-04-19 16:55:08 +08:00
parent 7cf9919ab0
commit 5367f25b4d
2 changed files with 18 additions and 2 deletions

View File

@ -3035,12 +3035,13 @@ static int32_t translateSelectList(STranslateContext* pCxt, SSelectStmt* pSelect
} }
static int32_t translateHaving(STranslateContext* pCxt, SSelectStmt* pSelect) { static int32_t translateHaving(STranslateContext* pCxt, SSelectStmt* pSelect) {
if (NULL == pSelect->pGroupByList && NULL != pSelect->pHaving) { if (NULL == pSelect->pGroupByList && NULL == pSelect->pPartitionByList && NULL == pSelect->pWindow &&
NULL != pSelect->pHaving) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION); return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION);
} }
pCxt->currClause = SQL_CLAUSE_HAVING; pCxt->currClause = SQL_CLAUSE_HAVING;
int32_t code = translateExpr(pCxt, &pSelect->pHaving); int32_t code = translateExpr(pCxt, &pSelect->pHaving);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code && (NULL != pSelect->pGroupByList || NULL != pSelect->pWindow)) {
code = checkExprForGroupBy(pCxt, &pSelect->pHaving); code = checkExprForGroupBy(pCxt, &pSelect->pHaving);
} }
return code; return code;

View File

@ -740,6 +740,13 @@ static int32_t createWindowLogicNodeFinalize(SLogicPlanContext* pCxt, SSelectStm
code = createColumnByRewriteExprs(pWindow->pFuncs, &pWindow->node.pTargets); code = createColumnByRewriteExprs(pWindow->pFuncs, &pWindow->node.pTargets);
} }
if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pHaving) {
pWindow->node.pConditions = nodesCloneNode(pSelect->pHaving);
if (NULL == pWindow->node.pConditions) {
code = TSDB_CODE_OUT_OF_MEMORY;
}
}
pSelect->hasAggFuncs = false; pSelect->hasAggFuncs = false;
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
@ -1132,6 +1139,14 @@ static int32_t createPartitionLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pS
} }
} }
if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pHaving && !pSelect->hasAggFuncs && NULL == pSelect->pGroupByList &&
NULL == pSelect->pWindow) {
pPartition->node.pConditions = nodesCloneNode(pSelect->pHaving);
if (NULL == pPartition->node.pConditions) {
code = TSDB_CODE_OUT_OF_MEMORY;
}
}
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
*pLogicNode = (SLogicNode*)pPartition; *pLogicNode = (SLogicNode*)pPartition;
} else { } else {