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