diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index dd9e32655f..dc43a3508f 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -510,29 +510,36 @@ int32_t stubCheckAndGetResultType(SFunctionNode* pFunc) { case FUNCTION_TYPE_CONCAT: case FUNCTION_TYPE_CONCAT_WS: { - int32_t paraTypeFirst, totalBytes = 0, sepBytes = 0; - int32_t firstParamIndex = 0; - if (pFunc->funcType == FUNCTION_TYPE_CONCAT_WS) { - firstParamIndex = 1; - SColumnNode* pSep = nodesListGetNode(pFunc->pParameterList, 0); - sepBytes = pSep->node.resType.type; - } - for (int32_t i = firstParamIndex; i < pFunc->pParameterList->length; ++i) { + int32_t paraType, paraBytes = 0; + for (int32_t i = 0; i < pFunc->pParameterList->length; ++i) { SColumnNode* pParam = nodesListGetNode(pFunc->pParameterList, i); - int32_t paraType = pParam->node.resType.type; - if (i == firstParamIndex) { - paraTypeFirst = paraType; - } - if (paraType != paraTypeFirst) { - return TSDB_CODE_FAILED; - } - //TODO: for constants also needs numOfRows - totalBytes += pParam->node.resType.bytes; + paraBytes += pParam->node.resType.bytes; + paraType = pParam->node.resType.type; } - //TODO: need to get numOfRows to decide how much space separator needed. Currently set to 100. - totalBytes += sepBytes * (pFunc->pParameterList->length - 2) * 100; - pFunc->node.resType = (SDataType) { .bytes = totalBytes, .type = paraTypeFirst }; - break; + pFunc->node.resType = (SDataType) { .bytes = paraBytes, .type = paraType }; + //int32_t paraTypeFirst, totalBytes = 0, sepBytes = 0; + //int32_t firstParamIndex = 0; + //if (pFunc->funcType == FUNCTION_TYPE_CONCAT_WS) { + // firstParamIndex = 1; + // SColumnNode* pSep = nodesListGetNode(pFunc->pParameterList, 0); + // sepBytes = pSep->node.resType.type; + //} + //for (int32_t i = firstParamIndex; i < pFunc->pParameterList->length; ++i) { + // SColumnNode* pParam = nodesListGetNode(pFunc->pParameterList, i); + // int32_t paraType = pParam->node.resType.type; + // if (i == firstParamIndex) { + // paraTypeFirst = paraType; + // } + // if (paraType != paraTypeFirst) { + // return TSDB_CODE_FAILED; + // } + // //TODO: for constants also needs numOfRows + // totalBytes += pParam->node.resType.bytes; + //} + ////TODO: need to get numOfRows to decide how much space separator needed. Currently set to 100. + //totalBytes += sepBytes * (pFunc->pParameterList->length - 2) * 100; + //pFunc->node.resType = (SDataType) { .bytes = totalBytes, .type = paraTypeFirst }; + //break; } case FUNCTION_TYPE_LOWER: case FUNCTION_TYPE_UPPER: diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index 9f481c8fb2..222f7ac69a 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -350,7 +350,7 @@ int32_t concatFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu } } - //allocate output buf + allocate output buf if (pOutputData->pData == NULL) { int32_t outputLen = inputLen + numOfRows * VARSTR_HEADER_SIZE; setVarTypeOutputBuf(pOutputData, outputLen, GET_PARAM_TYPE(pInput)); @@ -567,7 +567,7 @@ int32_t doTrimFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu } int32_t substrFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { - if (inputNum != 2 || inputNum!= 3) { + if (inputNum != 2 && inputNum!= 3) { return TSDB_CODE_FAILED; } @@ -589,16 +589,23 @@ int32_t substrFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu SColumnInfoData *pInputData = pInput->columnData; SColumnInfoData *pOutputData = pOutput->columnData; - for (int32_t i = 0; i < pOutput->numOfRows; ++i) { + //allocate output buf + if (pOutputData->pData == NULL) { + int32_t outputLen = pInputData->varmeta.length; + setVarTypeOutputBuf(pOutputData, outputLen, GET_PARAM_TYPE(pInput)); + } + + char *input = pInputData->pData; + char *output = pOutputData->pData; + + int32_t offset = 0; + for (int32_t i = 0; i < pInput->numOfRows; ++i) { if (colDataIsNull_f(pInputData->nullbitmap, i)) { colDataSetNull_f(pOutputData->nullbitmap, i); continue; } - char *in = pInputData->pData + i * GET_PARAM_BYTES(pInput); - char *out = pOutputData->pData + i * GET_PARAM_BYTES(pInput); - - int32_t len = varDataLen(in); + int32_t len = varDataLen(input); int32_t startPosBytes; if (subPos > 0) { @@ -611,10 +618,15 @@ int32_t substrFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu subLen = MIN(subLen, len - startPosBytes); if (subLen > 0) { - memcpy(varDataVal(out), varDataVal(in) + startPosBytes, subLen); + memcpy(varDataVal(output), varDataVal(input) + startPosBytes, subLen); } - varDataSetLen(out, subLen); + varDataSetLen(output, subLen); + input += varDataTLen(input); + output += varDataTLen(output); + + pOutputData->varmeta.offset[i] = offset; + offset += subLen + VARSTR_HEADER_SIZE; } pOutput->numOfRows = pInput->numOfRows;