Merge pull request #27348 from taosdata/fix/3.0/TD-31571

fix:[TD-31571] fix CONCAT function to return NULL when all input parameters are NULL
This commit is contained in:
dapan1121 2024-08-21 18:27:10 +08:00 committed by GitHub
commit 9b76e216a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 23 additions and 36 deletions

View File

@ -860,31 +860,27 @@ int32_t concatFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu
int32_t numOfRows = 0;
bool hasNchar = (GET_PARAM_TYPE(pOutput) == TSDB_DATA_TYPE_NCHAR) ? true : false;
for (int32_t i = 0; i < inputNum; ++i) {
if (pInput[i].numOfRows > numOfRows) {
numOfRows = pInput[i].numOfRows;
}
numOfRows = TMAX(pInput[i].numOfRows, numOfRows);
}
int32_t outputLen = VARSTR_HEADER_SIZE;
for (int32_t i = 0; i < inputNum; ++i) {
if (IS_NULL_TYPE(GET_PARAM_TYPE(&pInput[i]))) {
colDataSetNNULL(pOutputData, 0, numOfRows);
pOutput->numOfRows = numOfRows;
goto _return;
}
pInputData[i] = pInput[i].columnData;
int32_t factor = 1;
if (hasNchar && (GET_PARAM_TYPE(&pInput[i]) == TSDB_DATA_TYPE_VARCHAR)) {
factor = TSDB_NCHAR_SIZE;
}
int32_t numOfNulls = getNumOfNullEntries(pInputData[i], pInput[i].numOfRows);
if (pInput[i].numOfRows == 1) {
inputLen += (pInputData[i]->varmeta.length - VARSTR_HEADER_SIZE) * factor * (numOfRows - numOfNulls);
} else {
inputLen += (pInputData[i]->varmeta.length - (numOfRows - numOfNulls) * VARSTR_HEADER_SIZE) * factor;
}
outputLen += pInputData[i]->info.bytes * factor;
}
int32_t outputLen = inputLen + numOfRows * VARSTR_HEADER_SIZE;
outputBuf = taosMemoryCalloc(outputLen, 1);
if (NULL == outputBuf) {
SCL_ERR_JRET(TSDB_CODE_OUT_OF_MEMORY);
}
char *output = outputBuf;
for (int32_t k = 0; k < numOfRows; ++k) {
bool hasNull = false;
@ -901,6 +897,7 @@ int32_t concatFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu
}
VarDataLenT dataLen = 0;
char *output = outputBuf;
for (int32_t i = 0; i < inputNum; ++i) {
int32_t rowIdx = (pInput[i].numOfRows == 1) ? 0 : k;
input[i] = colDataGetData(pInputData[i], rowIdx);
@ -908,8 +905,7 @@ int32_t concatFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu
SCL_ERR_JRET(concatCopyHelper(input[i], output, hasNchar, GET_PARAM_TYPE(&pInput[i]), &dataLen));
}
varDataSetLen(output, dataLen);
SCL_ERR_JRET(colDataSetVal(pOutputData, k, output, false));
output += varDataTLen(output);
SCL_ERR_JRET(colDataSetVal(pOutputData, k, outputBuf, false));
}
pOutput->numOfRows = numOfRows;
@ -926,51 +922,44 @@ int32_t concatWsFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *p
int32_t code = TSDB_CODE_SUCCESS;
SColumnInfoData **pInputData = taosMemoryCalloc(inputNum, sizeof(SColumnInfoData *));
SColumnInfoData *pOutputData = pOutput->columnData;
char **input = taosMemoryCalloc(inputNum, POINTER_BYTES);
char *outputBuf = NULL;
if (NULL == pInputData) {
SCL_ERR_JRET(TSDB_CODE_OUT_OF_MEMORY);
}
if (NULL == input) {
SCL_ERR_JRET(TSDB_CODE_OUT_OF_MEMORY);
}
int32_t inputLen = 0;
int32_t numOfRows = 0;
bool hasNchar = (GET_PARAM_TYPE(pOutput) == TSDB_DATA_TYPE_NCHAR) ? true : false;
for (int32_t i = 1; i < inputNum; ++i) {
if (pInput[i].numOfRows > numOfRows) {
numOfRows = pInput[i].numOfRows;
}
}
for (int32_t i = 0; i < inputNum; ++i) {
numOfRows = TMAX(pInput[i].numOfRows, numOfRows);
}
int32_t outputLen = VARSTR_HEADER_SIZE;
for (int32_t i = 0; i < inputNum; ++i) {
if (IS_NULL_TYPE(GET_PARAM_TYPE(&pInput[i]))) {
colDataSetNNULL(pOutputData, 0, numOfRows);
pOutput->numOfRows = numOfRows;
goto _return;
}
pInputData[i] = pInput[i].columnData;
int32_t factor = 1;
if (hasNchar && (GET_PARAM_TYPE(&pInput[i]) == TSDB_DATA_TYPE_VARCHAR)) {
factor = TSDB_NCHAR_SIZE;
}
int32_t numOfNulls = getNumOfNullEntries(pInputData[i], pInput[i].numOfRows);
if (i == 0) {
// calculate required separator space
inputLen +=
(pInputData[0]->varmeta.length - VARSTR_HEADER_SIZE) * (numOfRows - numOfNulls) * (inputNum - 2) * factor;
} else if (pInput[i].numOfRows == 1) {
inputLen += (pInputData[i]->varmeta.length - VARSTR_HEADER_SIZE) * (numOfRows - numOfNulls) * factor;
outputLen += pInputData[i]->info.bytes * factor * (inputNum - 2);
} else {
inputLen += (pInputData[i]->varmeta.length - (numOfRows - numOfNulls) * VARSTR_HEADER_SIZE) * factor;
outputLen += pInputData[i]->info.bytes * factor;
}
}
int32_t outputLen = inputLen + numOfRows * VARSTR_HEADER_SIZE;
outputBuf = taosMemoryCalloc(outputLen, 1);
if (NULL == outputBuf) {
SCL_ERR_JRET(TSDB_CODE_OUT_OF_MEMORY);
}
char *output = outputBuf;
for (int32_t k = 0; k < numOfRows; ++k) {
if (colDataIsNull_s(pInputData[0], k) || IS_NULL_TYPE(GET_PARAM_TYPE(&pInput[0]))) {
colDataSetNULL(pOutputData, k);
@ -979,6 +968,7 @@ int32_t concatWsFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *p
VarDataLenT dataLen = 0;
bool hasNull = false;
char *output = outputBuf;
for (int32_t i = 1; i < inputNum; ++i) {
if (colDataIsNull_s(pInputData[i], k) || IS_NULL_TYPE(GET_PARAM_TYPE(&pInput[i]))) {
hasNull = true;
@ -986,9 +976,8 @@ int32_t concatWsFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *p
}
int32_t rowIdx = (pInput[i].numOfRows == 1) ? 0 : k;
input[i] = colDataGetData(pInputData[i], rowIdx);
SCL_ERR_JRET(concatCopyHelper(input[i], output, hasNchar, GET_PARAM_TYPE(&pInput[i]), &dataLen));
SCL_ERR_JRET(concatCopyHelper(colDataGetData(pInputData[i], rowIdx), output, hasNchar, GET_PARAM_TYPE(&pInput[i]), &dataLen));
if (i < inputNum - 1) {
// insert the separator
@ -1003,14 +992,12 @@ int32_t concatWsFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *p
} else {
varDataSetLen(output, dataLen);
SCL_ERR_JRET(colDataSetVal(pOutputData, k, output, false));
output += varDataTLen(output);
}
}
pOutput->numOfRows = numOfRows;
_return:
taosMemoryFree(input);
taosMemoryFree(outputBuf);
taosMemoryFree(pInputData);