diff --git a/source/libs/function/inc/tbinoperator.h b/source/libs/function/inc/tbinoperator.h index 65b9ce1bdebe9e554ffdb498a5a427f01ceb195b..c1b6b0bc312dd57ad65dda6d429124a4d1ce71e4 100644 --- a/source/libs/function/inc/tbinoperator.h +++ b/source/libs/function/inc/tbinoperator.h @@ -24,6 +24,7 @@ extern "C" { typedef void (*_bin_scalar_fn_t)(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *output, int32_t order); _bin_scalar_fn_t getBinScalarOperatorFn(int32_t binOperator); +bool isBinaryStringOp(int32_t op); #ifdef __cplusplus } diff --git a/source/libs/function/src/tbinoperator.c b/source/libs/function/src/tbinoperator.c index 902c0054a03e338c251d8ce67d11b80e83197258..1803e282bf0abe564e4c56ae96524250f46d7b65 100644 --- a/source/libs/function/src/tbinoperator.c +++ b/source/libs/function/src/tbinoperator.c @@ -482,3 +482,7 @@ _bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) { return NULL; } } + +bool isBinaryStringOp(int32_t op) { + return op == TSDB_BINARY_OP_CONCAT; +} diff --git a/source/libs/function/src/tscalarfunction.c b/source/libs/function/src/tscalarfunction.c index 8da1a9d5824a118d090c120ba837d3803de97e57..b3ffb19d7b93ffa33416f8dc62063148d4e52e15 100644 --- a/source/libs/function/src/tscalarfunction.c +++ b/source/libs/function/src/tscalarfunction.c @@ -74,6 +74,10 @@ static void setScalarFuncParam(SScalarFuncParam* param, int32_t type, int32_t by param->data = pInput; } +bool isStringOp(int32_t op) { + return op == TSDB_BINARY_OP_CONCAT; +} + int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncParam* pOutput, void* param, char* (*getSourceDataBlock)(void*, const char*, int32_t)) { if (pExprs == NULL) { @@ -87,16 +91,14 @@ int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncPa SScalarFuncParam leftOutput = {0}; SScalarFuncParam rightOutput = {0}; - leftOutput.data = malloc(sizeof(int64_t) * numOfRows); - if (pLeft->nodeType == TEXPR_BINARYEXPR_NODE || pLeft->nodeType == TEXPR_UNARYEXPR_NODE) { + leftOutput.data = malloc(sizeof(int64_t) * numOfRows); evaluateExprNodeTree(pLeft, numOfRows, &leftOutput, param, getSourceDataBlock); } // the right output has result from the right child syntax tree - rightOutput.data = malloc(sizeof(int64_t) * numOfRows); - - if (pRight->nodeType == TEXPR_BINARYEXPR_NODE) { + if (pRight->nodeType == TEXPR_BINARYEXPR_NODE || pRight->nodeType == TEXPR_UNARYEXPR_NODE) { + rightOutput.data = malloc(sizeof(int64_t) * numOfRows); evaluateExprNodeTree(pRight, numOfRows, &rightOutput, param, getSourceDataBlock); } @@ -114,8 +116,6 @@ int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncPa } else if (pLeft->nodeType == TEXPR_VALUE_NODE) { SVariant* pVar = pRight->pVal; setScalarFuncParam(&left, pVar->nType, pVar->nLen, &pVar->i, 1); - } else { - assert(0); } if (pRight->nodeType == TEXPR_BINARYEXPR_NODE || pRight->nodeType == TEXPR_UNARYEXPR_NODE) { @@ -127,14 +127,16 @@ int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncPa } else if (pRight->nodeType == TEXPR_VALUE_NODE) { // exprLeft + 12 SVariant* pVar = pRight->pVal; setScalarFuncParam(&right, pVar->nType, pVar->nLen, &pVar->i, 1); - } else { - assert(0); } - OperatorFn(&left, &right, pOutput->data, TSDB_ORDER_ASC); + void* outputBuf = pOutput->data; + if (isStringOp(pExprs->_node.optr)) { + outputBuf = realloc(pOutput->data, (left.bytes + right.bytes) * left.num); + OperatorFn(&left, &right, outputBuf, TSDB_ORDER_ASC); + } // Set the result info - setScalarFuncParam(pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double), pOutput->data, numOfRows); + setScalarFuncParam(pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double), outputBuf, numOfRows); } else if (pExprs->nodeType == TEXPR_UNARYEXPR_NODE) { _unary_scalar_fn_t OperatorFn = getUnaryScalarOperatorFn(pExprs->_node.optr); SScalarFuncParam left = {0}; @@ -148,8 +150,13 @@ int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncPa } else if (pLeft->nodeType == TEXPR_VALUE_NODE) { SVariant* pVar = pLeft->pVal; setScalarFuncParam(&left, pVar->nType, pVar->nLen, &pVar->i, 1); - } else { - assert(0); + } + + // reserve enough memory buffer + if (isBinaryStringOp(pExprs->_node.optr)) { + void* outputBuf = realloc(pOutput->data, left.bytes * left.num); + assert(outputBuf != NULL); + pOutput->data = outputBuf; } OperatorFn(&left, pOutput); diff --git a/source/libs/function/src/tunaryoperator.c b/source/libs/function/src/tunaryoperator.c index dc9727d84179b322643f636ee488dddb0632fa7a..9105942d26bd2d4a9a9e271cc175f37b8496b1e5 100644 --- a/source/libs/function/src/tunaryoperator.c +++ b/source/libs/function/src/tunaryoperator.c @@ -165,3 +165,7 @@ _unary_scalar_fn_t getUnaryScalarOperatorFn(int32_t operator) { assert(0); } } + +bool isStringOperatorFn(int32_t op) { + return op == TSDB_UNARY_OP_LEN; +}