fix: colref
This commit is contained in:
parent
45ec9fcbc8
commit
d243308541
|
@ -531,6 +531,7 @@ int32_t nodesCollectColumnsFromNode(SNode* node, const char* pTableAlias, EColle
|
|||
|
||||
typedef bool (*FFuncClassifier)(int32_t funcId);
|
||||
int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAlias, FFuncClassifier classifier, SNodeList** pFuncs);
|
||||
int32_t nodesCollectSelectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAlias, FFuncClassifier classifier, SNodeList** pFuncs);
|
||||
|
||||
int32_t nodesCollectSpecialNodes(SSelectStmt* pSelect, ESqlClause clause, ENodeType type, SNodeList** pNodes);
|
||||
|
||||
|
|
|
@ -1477,17 +1477,18 @@ void createExprFromOneNode(SExprInfo* pExp, SNode* pNode, int16_t slotId) {
|
|||
SValueNode* pvn = (SValueNode*)p1;
|
||||
pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE;
|
||||
nodesValueNodeToVariant(pvn, &pExp->base.pParam[j].param);
|
||||
} else if (p1->type == QUERY_NODE_FUNCTION) {
|
||||
if (strcmp(((SFunctionNode*)p1)->functionName, "_select_value") == 0 &&
|
||||
((SFunctionNode*)p1)->pParameterList->length == 1 &&
|
||||
((SFunctionNode*)p1)->pParameterList->pHead->pNode->type == QUERY_NODE_COLUMN) {
|
||||
SColumnNode* pcn = (SColumnNode*)(((SFunctionNode*)p1)->pParameterList->pHead->pNode);
|
||||
SValueNode* pvn = (SValueNode*)p1;
|
||||
pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
|
||||
pExp->base.pParam[j].pCol =
|
||||
createColumn(pcn->dataBlockId, pcn->slotId, pcn->colId, &pcn->node.resType, pcn->colType);
|
||||
}
|
||||
}
|
||||
}
|
||||
// else if (p1->type == QUERY_NODE_FUNCTION) {
|
||||
// if (strcmp(((SFunctionNode*)p1)->functionName, "_select_value") == 0 &&
|
||||
// ((SFunctionNode*)p1)->pParameterList->length == 1 &&
|
||||
// ((SFunctionNode*)p1)->pParameterList->pHead->pNode->type == QUERY_NODE_COLUMN) {
|
||||
// SColumnNode* pcn = (SColumnNode*)(((SFunctionNode*)p1)->pParameterList->pHead->pNode);
|
||||
// SValueNode* pvn = (SValueNode*)p1;
|
||||
// pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN;
|
||||
// pExp->base.pParam[j].pCol =
|
||||
// createColumn(pcn->dataBlockId, pcn->slotId, pcn->colId, &pcn->node.resType, pcn->colType);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
} else if (type == QUERY_NODE_OPERATOR) {
|
||||
pExp->pExpr->nodeType = QUERY_NODE_OPERATOR;
|
||||
|
|
|
@ -2111,6 +2111,34 @@ static EDealRes collectFuncs(SNode* pNode, void* pContext) {
|
|||
FOREACH(pn, pCxt->pFuncs) {
|
||||
if (nodesEqualNode(pn, pNode)) {
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bFound) {
|
||||
pCxt->errCode = nodesListStrictAppend(pCxt->pFuncs, nodesCloneNode(pNode));
|
||||
}
|
||||
return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static EDealRes collectSelectFuncs(SNode* pNode, void* pContext) {
|
||||
SCollectFuncsCxt* pCxt = (SCollectFuncsCxt*)pContext;
|
||||
if (QUERY_NODE_FUNCTION == nodeType(pNode) && pCxt->classifier(((SFunctionNode*)pNode)->funcId)) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
if (FUNCTION_TYPE_TBNAME == pFunc->funcType && pCxt->tableAlias) {
|
||||
SValueNode* pVal = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
if (pVal && strcmp(pVal->literal, pCxt->tableAlias)) {
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
}
|
||||
SExprNode* pExpr = (SExprNode*)pNode;
|
||||
bool bFound = false;
|
||||
SNode* pn = NULL;
|
||||
FOREACH(pn, pCxt->pFuncs) {
|
||||
if (nodesEqualNode(pn, pNode)) {
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bFound) {
|
||||
|
@ -2133,6 +2161,33 @@ static int32_t funcNodeEqual(const void* pLeft, const void* pRight, size_t len)
|
|||
return nodesEqualNode(*(const SNode**)pLeft, *(const SNode**)pRight) ? 0 : 1;
|
||||
}
|
||||
|
||||
int32_t nodesCollectSelectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAlias, FFuncClassifier classifier, SNodeList** pFuncs) {
|
||||
if (NULL == pSelect || NULL == pFuncs) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
SCollectFuncsCxt cxt = {.errCode = TSDB_CODE_SUCCESS,
|
||||
.classifier = classifier,
|
||||
.tableAlias = tableAlias,
|
||||
.pFuncs = *pFuncs};
|
||||
if (NULL == cxt.pFuncs) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nodesWalkSelectStmt(pSelect, clause, collectFuncs, &cxt);
|
||||
if (TSDB_CODE_SUCCESS == cxt.errCode) {
|
||||
if (LIST_LENGTH(cxt.pFuncs) > 0) {
|
||||
*pFuncs = cxt.pFuncs;
|
||||
} else {
|
||||
nodesDestroyList(cxt.pFuncs);
|
||||
}
|
||||
} else {
|
||||
nodesDestroyList(cxt.pFuncs);
|
||||
}
|
||||
|
||||
return cxt.errCode;
|
||||
}
|
||||
|
||||
int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAlias, FFuncClassifier classifier, SNodeList** pFuncs) {
|
||||
if (NULL == pSelect || NULL == pFuncs) {
|
||||
return TSDB_CODE_FAILED;
|
||||
|
@ -2152,9 +2207,11 @@ int32_t nodesCollectFuncs(SSelectStmt* pSelect, ESqlClause clause, char* tableAl
|
|||
*pFuncs = cxt.pFuncs;
|
||||
} else {
|
||||
nodesDestroyList(cxt.pFuncs);
|
||||
*pFuncs = NULL;
|
||||
}
|
||||
} else {
|
||||
nodesDestroyList(cxt.pFuncs);
|
||||
*pFuncs = NULL;
|
||||
}
|
||||
|
||||
return cxt.errCode;
|
||||
|
|
|
@ -2744,6 +2744,24 @@ static EDealRes doCheckAggColCoexist(SNode** pNode, void* pContext) {
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t reCalSelectFuncNum(SSelectStmt* pSelect) {
|
||||
pSelect->selectFuncNum = 0;
|
||||
SNodeList* pNodeList = nodesMakeList();
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
for (ESqlClause clause = SQL_CLAUSE_FROM; clause < SQL_CLAUSE_ORDER_BY; clause++) {
|
||||
code = nodesCollectSelectFuncs(pSelect, clause, NULL, fmIsSelectFunc, &pNodeList);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pNodeList) {
|
||||
pSelect->selectFuncNum = calcSelectFuncNum((SFunctionNode*)pNode, pSelect->selectFuncNum);
|
||||
}
|
||||
nodesDestroyList(pNodeList);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (NULL != pSelect->pGroupByList || NULL != pSelect->pWindow ||
|
||||
(!pSelect->hasAggFuncs && !pSelect->hasIndefiniteRowsFunc && !pSelect->hasInterpFunc)) {
|
||||
|
@ -2757,7 +2775,8 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
|||
if (!pSelect->isDistinct) {
|
||||
nodesRewriteExprs(pSelect->pOrderByList, doCheckAggColCoexist, &cxt);
|
||||
}
|
||||
if (0 < pSelect->selectFuncNum && !pSelect->hasOtherVectorFunc) {
|
||||
if (((!cxt.existCol && 0 < pSelect->selectFuncNum) || (cxt.existCol && 1 == pSelect->selectFuncNum) )
|
||||
&& !pSelect->hasOtherVectorFunc) {
|
||||
return rewriteColsToSelectValFunc(pCxt, pSelect);
|
||||
}
|
||||
if (cxt.existCol) {
|
||||
|
@ -4597,6 +4616,7 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
|
|||
code = translateOrderBy(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
reCalSelectFuncNum(pSelect);
|
||||
code = checkAggColCoexist(pCxt, pSelect);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
|
Loading…
Reference in New Issue