diff --git a/source/libs/executor/src/executorInt.c b/source/libs/executor/src/executorInt.c index 00138d6871..1659c1fa3e 100644 --- a/source/libs/executor/src/executorInt.c +++ b/source/libs/executor/src/executorInt.c @@ -1010,6 +1010,10 @@ static void destroySqlFunctionCtx(SqlFunctionCtx* pCtx, SExprInfo* pExpr, int32_ } for (int32_t i = 0; i < numOfOutput; ++i) { + if (pCtx[i].fpSet.cleanup != NULL) { + pCtx[i].fpSet.cleanup(&pCtx[i]); + } + if (pExpr != NULL) { SExprInfo* pExprInfo = &pExpr[i]; for (int32_t j = 0; j < pExprInfo->base.numOfParams; ++j) { diff --git a/source/libs/executor/src/operator.c b/source/libs/executor/src/operator.c index 6fe270161f..8fe8c6363a 100644 --- a/source/libs/executor/src/operator.c +++ b/source/libs/executor/src/operator.c @@ -659,10 +659,6 @@ void destroyOperator(SOperatorInfo* pOperator) { freeResetOperatorParams(pOperator, OP_GET_PARAM, true); freeResetOperatorParams(pOperator, OP_NOTIFY_PARAM, true); - if (pOperator->fpSet.closeFn != NULL && pOperator->info != NULL) { - pOperator->fpSet.closeFn(pOperator->info); - } - if (pOperator->pDownstream != NULL) { for (int32_t i = 0; i < pOperator->numOfRealDownstream; ++i) { destroyOperator(pOperator->pDownstream[i]); @@ -673,6 +669,12 @@ void destroyOperator(SOperatorInfo* pOperator) { } cleanupExprSupp(&pOperator->exprSupp); + + // close operator after cleanup exprSupp, since we need to call cleanup of sqlFunctionCtx first to avoid mem leak. + if (pOperator->fpSet.closeFn != NULL && pOperator->info != NULL) { + pOperator->fpSet.closeFn(pOperator->info); + } + taosMemoryFreeClear(pOperator); } diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index 6d655528c7..c55839d033 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -6036,9 +6036,10 @@ static void modeFunctionCleanup(SModeInfo * pInfo) { } void modeFunctionCleanupExt(SqlFunctionCtx* pCtx) { - SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); - SModeInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo); - modeFunctionCleanup(pInfo); + if (pCtx == NULL || GET_RES_INFO(pCtx) == NULL || GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)) == NULL) { + return; + } + modeFunctionCleanup(GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx))); } static int32_t saveModeTupleData(SqlFunctionCtx* pCtx, char* data, SModeInfo *pInfo, STuplePos* pPos) {