diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 51f30aca21458a34d5928bf3169dc4d3f70611ae..e41e3c7c39a2a18e262e892cf659fd3258361ace 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -387,7 +387,8 @@ static int32_t translateSample(SFunctionNode* pFunc, char* pErrBuf, int32_t len) } static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { - if (2 != LIST_LENGTH(pFunc->pParameterList)) { + int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList); + if (2 != numOfParams && 3 != numOfParams) { return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } @@ -397,9 +398,11 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { "The input parameter of TAIL function can only be column"); } - uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type; - if (!IS_INTEGER_TYPE(paraType)) { - return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); + for (int32_t i = 1; i < numOfParams; ++i) { + uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, i))->resType.type; + if (!IS_INTEGER_TYPE(paraType)) { + return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); + } } SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0); diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index add33adb086d59357c6a1ad141edf90fa1c48a3e..479a11ca4a2d38321c93c1bba7941f1874a76073 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -3177,7 +3177,11 @@ bool tailFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo *pResultInfo) { STailInfo *pInfo = GET_ROWCELL_INTERBUF(pResultInfo); pInfo->numAdded = 0; pInfo->numOfPoints = pCtx->param[1].param.i; - pInfo->offset = pCtx->param[2].param.i; + if (pCtx->numOfParams == 4) { + pInfo->offset = pCtx->param[2].param.i; + } else { + pInfo->offset = 0; + } pInfo->colType = pCtx->resDataInfo.type; pInfo->colBytes = pCtx->resDataInfo.bytes; if ((pInfo->numOfPoints < 1 || pInfo->numOfPoints > TAIL_MAX_POINTS_NUM) || @@ -3236,8 +3240,12 @@ int32_t tailFunction(SqlFunctionCtx* pCtx) { SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput; int32_t startOffset = pCtx->offset; - pInfo->numOfPoints = MIN(pInfo->numOfPoints, pInput->numOfRows); - for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; i += 1) { + if (pInfo->offset >= pInput->numOfRows) { + return 0; + } else { + pInfo->numOfPoints = MIN(pInfo->numOfPoints, pInput->numOfRows - pInfo->offset); + } + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex - pInfo->offset; i += 1) { char* data = colDataGetData(pInputCol, i); doTailAdd(pInfo, data, tsList[i], colDataIsNull_s(pInputCol, i));