From f2dcd3f16adb5aa1738d58a93014e17b97c01543 Mon Sep 17 00:00:00 2001 From: sima Date: Thu, 15 Aug 2024 15:20:10 +0800 Subject: [PATCH] fix:[TD-31470] Fix replace function wrong length. --- source/libs/function/src/builtins.c | 17 ++++++++++++++--- source/libs/scalar/src/sclfunc.c | 16 +++++++++++++++- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index e6724f9e0a..760a3c4a33 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -2327,13 +2327,24 @@ static int32_t translateReplace(SFunctionNode* pFunc, char* pErrBuf, int32_t len } } - uint8_t type = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type; + uint8_t orgType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type; + uint8_t fromType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->type; + uint8_t toType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->type; int32_t orgLen = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->bytes; int32_t fromLen = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 1))->bytes; int32_t toLen = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 2))->bytes; - int32_t resLen = orgLen + orgLen / fromLen * (toLen - fromLen); - pFunc->node.resType = (SDataType){.bytes = resLen, .type = type}; + int32_t resLen; + // Since we don't know the accurate length of result, estimate the maximum length here. + // To make the resLen bigger, we should make fromLen smaller and toLen bigger. + if (orgType == TSDB_DATA_TYPE_VARBINARY && fromType != orgType) { + fromLen = fromLen / TSDB_NCHAR_SIZE; + } + if (orgType == TSDB_DATA_TYPE_NCHAR && toType != orgType) { + toLen = toLen * TSDB_NCHAR_SIZE; + } + resLen = TMAX(orgLen, orgLen + orgLen / fromLen * (toLen - fromLen)); + pFunc->node.resType = (SDataType){.bytes = resLen, .type = orgType}; return TSDB_CODE_SUCCESS; } diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index a666404838..fde87ba4f1 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1458,7 +1458,21 @@ int32_t replaceFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pO numOfRows = TMAX(numOfRows, pInput[i].numOfRows); } - outputLen = pInputData[0]->info.bytes + pInputData[0]->info.bytes / pInputData[1]->info.bytes * (pInputData[2]->info.bytes - pInputData[1]->info.bytes); + int8_t orgType = pInputData[0]->info.type; + int8_t fromType = pInputData[1]->info.type; + int8_t toType = pInputData[2]->info.type; + int32_t orgLength = pInputData[0]->info.bytes; + int32_t fromLength = pInputData[1]->info.bytes; + int32_t toLength = pInputData[2]->info.bytes; + + if (orgType == TSDB_DATA_TYPE_VARBINARY && fromType != orgType) { + fromLength = fromLength / TSDB_NCHAR_SIZE; + } + if (orgType == TSDB_DATA_TYPE_NCHAR && toType != orgType) { + toLength = toLength * TSDB_NCHAR_SIZE; + } + outputLen = TMAX(orgLength, orgLength + orgLength / fromLength * (toLength - fromLength)); + if (GET_PARAM_TYPE(&pInput[0]) == TSDB_DATA_TYPE_NULL || GET_PARAM_TYPE(&pInput[1]) == TSDB_DATA_TYPE_NULL || GET_PARAM_TYPE(&pInput[2]) == TSDB_DATA_TYPE_NULL ||