diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c index a406b23c59..5dfb94ba6e 100644 --- a/source/libs/function/src/functionMgt.c +++ b/source/libs/function/src/functionMgt.c @@ -412,6 +412,13 @@ int32_t createFunction(const char* pName, SNodeList* pParameterList, SFunctionNo return code; } +static void resetOutputChangedFunc(SFunctionNode *pFunc, const SFunctionNode* pSrcFunc) { + if (funcMgtBuiltins[pFunc->funcId].type == FUNCTION_TYPE_LAST_MERGE) { + pFunc->node.resType = pSrcFunc->node.resType; + return; + } +} + int32_t createFunctionWithSrcFunc(const char* pName, const SFunctionNode* pSrcFunc, SNodeList* pParameterList, SFunctionNode** ppFunc) { int32_t code = nodesMakeNode(QUERY_NODE_FUNCTION, (SNode**)ppFunc); if (NULL == *ppFunc) { @@ -430,6 +437,7 @@ int32_t createFunctionWithSrcFunc(const char* pName, const SFunctionNode* pSrcFu *ppFunc = NULL; return code; } + resetOutputChangedFunc(*ppFunc, pSrcFunc); return code; } diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 39024731ed..0cc26dfce9 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -4258,7 +4258,7 @@ typedef struct SLastRowScanOptSetColDataTypeCxt { int32_t code; } SLastRowScanOptSetColDataTypeCxt; -static EDealRes lastRowScanOptSetColDataType(SNode* pNode, void* pContext) { +static EDealRes lastRowScanOptGetColAndSetDataType(SNode* pNode, void* pContext, bool setType) { if (QUERY_NODE_COLUMN == nodeType(pNode)) { SLastRowScanOptSetColDataTypeCxt* pCxt = pContext; if (pCxt->doAgg) { @@ -4266,12 +4266,12 @@ static EDealRes lastRowScanOptSetColDataType(SNode* pNode, void* pContext) { if (TSDB_CODE_SUCCESS != pCxt->code) { return DEAL_RES_ERROR; } - getLastCacheDataType(&(((SColumnNode*)pNode)->node.resType), pCxt->pkBytes); + if (setType) getLastCacheDataType(&(((SColumnNode*)pNode)->node.resType), pCxt->pkBytes); } else { SNode* pCol = NULL; FOREACH(pCol, pCxt->pLastCols) { if (nodesEqualNode(pCol, pNode)) { - getLastCacheDataType(&(((SColumnNode*)pNode)->node.resType), pCxt->pkBytes); + if (setType) getLastCacheDataType(&(((SColumnNode*)pNode)->node.resType), pCxt->pkBytes); break; } } @@ -4281,6 +4281,14 @@ static EDealRes lastRowScanOptSetColDataType(SNode* pNode, void* pContext) { return DEAL_RES_CONTINUE; } +static EDealRes lastRowScanOptGetLastCols(SNode* pNode, void* pContext) { + return lastRowScanOptGetColAndSetDataType(pNode, pContext, false); +} + +static EDealRes lastRowScanOptSetColDataType(SNode* pNode, void* pContext) { + return lastRowScanOptGetColAndSetDataType(pNode, pContext, true); +} + static void lastRowScanOptSetLastTargets(SNodeList* pTargets, SNodeList* pLastCols, SNodeList* pLastRowCols, bool erase, int32_t pkBytes) { SNode* pTarget = NULL; WHERE_EACH(pTarget, pTargets) { @@ -4393,7 +4401,7 @@ static int32_t lastRowScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogic SNode* pParamNode = NULL; if (FUNCTION_TYPE_LAST == funcType) { (void)nodesListErase(pFunc->pParameterList, nodesListGetCell(pFunc->pParameterList, 1)); - nodesWalkExpr(nodesListGetNode(pFunc->pParameterList, 0), lastRowScanOptSetColDataType, &cxt); + nodesWalkExpr(nodesListGetNode(pFunc->pParameterList, 0), lastRowScanOptGetLastCols, &cxt); if (TSDB_CODE_SUCCESS != cxt.code) break; } FOREACH(pParamNode, pFunc->pParameterList) {