提交 f9c57f28 编写于 作者: S shenglian zhou

support concat strings

上级 5cbb2da4
......@@ -1759,13 +1759,6 @@ static int32_t handleScalarExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t e
// expr string is set as the parameter of function
SColumnIndex index = {.tableIndex = tableIndex};
SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double),
getNewResColId(pCmd), sizeof(double), false);
char* name = (pItem->aliasName != NULL)? pItem->aliasName:pItem->pNode->exprToken.z;
size_t len = MIN(sizeof(pExpr->base.aliasName), pItem->pNode->exprToken.n + 1);
tstrncpy(pExpr->base.aliasName, name, len);
tExprNode* pNode = NULL;
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
......@@ -1795,6 +1788,14 @@ static int32_t handleScalarExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t e
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, pNode->resultType, pNode->resultBytes,
getNewResColId(pCmd), 0, false);
char* name = (pItem->aliasName != NULL)? pItem->aliasName:pItem->pNode->exprToken.z;
size_t len = MIN(sizeof(pExpr->base.aliasName), pItem->pNode->exprToken.n + 1);
tstrncpy(pExpr->base.aliasName, name, len);
SBufferWriter bw = tbufInitWriter(NULL, false);
TRY(0) {
......@@ -1811,7 +1812,7 @@ static int32_t handleScalarExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t e
// set the serialized binary string as the parameter of arithmetic expression
tscExprAddParams(&pExpr->base, c, TSDB_DATA_TYPE_BINARY, (int32_t)len);
if (finalResult) {
insertResultField(pQueryInfo, exprIndex, columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->base.aliasName,
insertResultField(pQueryInfo, exprIndex, columnList, pExpr->base.resBytes, pExpr->base.resType, pExpr->base.aliasName,
pExpr);
}
......@@ -4498,15 +4499,6 @@ static int32_t validateSQLExprItem(SSqlCmd* pCmd, tSqlExpr* pExpr,
return TSDB_CODE_TSC_INVALID_OPERATION;
}
// if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
SSchema* pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex;
if ((pSchema->type == TSDB_DATA_TYPE_TIMESTAMP) || (pSchema->type == TSDB_DATA_TYPE_BOOL) ||
(pSchema->type == TSDB_DATA_TYPE_BINARY) || (pSchema->type == TSDB_DATA_TYPE_NCHAR)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pList->ids[pList->num++] = index;
} else if ((pExpr->tokenId == TK_FLOAT && (isnan(pExpr->value.dKey) || isinf(pExpr->value.dKey))) ||
pExpr->tokenId == TK_NULL) {
......
......@@ -66,9 +66,12 @@ int32_t exprTreeValidateFunctionNode(tExprNode *pExpr) {
tExprNode *child1 = pExpr->_func.pChildren[0];
tExprNode *child2 = pExpr->_func.pChildren[1];
if (child1->nodeType == TSQL_NODE_VALUE) {
return TSDB_CODE_TSC_INVALID_OPERATION;
} else if (!IS_VAR_DATA_TYPE(child1->resultType)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
if (!IS_VAR_DATA_TYPE(child1->resultType)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
tVariantTypeSetType(child1->pVal, (char)(child1->resultType));
child1->resultType = (int16_t)child2->pVal->nType;
child1->resultBytes = (int16_t)(child2->pVal->nLen + VARSTR_HEADER_SIZE);
}
if (child2->nodeType == TSQL_NODE_VALUE) {
......@@ -80,15 +83,14 @@ int32_t exprTreeValidateFunctionNode(tExprNode *pExpr) {
child2->resultBytes = (int16_t)(child2->pVal->nLen + VARSTR_HEADER_SIZE);
}
if (child1->resultType != child2->resultType) {
if (child1->resultType != child2->resultType || (!IS_VAR_DATA_TYPE(child1->resultType))) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->resultType = child1->resultType;
pExpr->resultBytes = child1->resultBytes + child2->resultBytes - VARSTR_HEADER_SIZE;
break;
}
default:
break;
}
......@@ -100,6 +102,7 @@ int32_t exprTreeValidateExprNode(tExprNode *pExpr) {
if (pExpr->_node.optr == TSDB_BINARY_OP_ADD || pExpr->_node.optr == TSDB_BINARY_OP_SUBTRACT ||
pExpr->_node.optr == TSDB_BINARY_OP_MULTIPLY || pExpr->_node.optr == TSDB_BINARY_OP_DIVIDE ||
pExpr->_node.optr == TSDB_BINARY_OP_REMAINDER) {
pExpr->resultType = TSDB_DATA_TYPE_DOUBLE;
pExpr->resultBytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes;
return TSDB_CODE_SUCCESS;
......@@ -380,7 +383,7 @@ void exprTreeFunctionNodeTraverse(tExprNode *pExpr, int32_t numOfRows, tExprOper
} else {
pInputs[i].data = pInputData;
}
pInputs[i].numOfRows = numOfRows;
pInputs[i].numOfRows = (int16_t)numOfRows;
} else if (pChild->nodeType == TSQL_NODE_VALUE) {
pChildrenOutput[i] = malloc(pChild->resultBytes);
tVariantDump(pChild->pVal, pChildrenOutput[i], pChild->resultType, true);
......@@ -392,8 +395,8 @@ void exprTreeFunctionNodeTraverse(tExprNode *pExpr, int32_t numOfRows, tExprOper
_expr_scalar_function_t scalarFn = getExprScalarFunction(pExpr->_func.functionId);
output->type = pExpr->resultType;
output->bytes = pExpr->resultBytes;
scalarFn(pExpr->_func.functionId, pInputs, numChildren, output, order);
output->numOfRows = numOfRows;
output->numOfRows = (int16_t)numOfRows;
scalarFn(pExpr->_func.functionId, pInputs, numChildren, output, TSDB_ORDER_ASC);
tfree(pChildrenResults);
for (int i = 0; i < numChildren; ++i) {
......@@ -933,7 +936,37 @@ void vectorLog(int16_t functionId, tExprOperandInfo* pInputs, uint8_t numInputs,
}
void vectorConcat(int16_t functionId, tExprOperandInfo* pInputs, uint8_t numInputs, tExprOperandInfo* pOutput, int32_t order) {
assert(functionId == TSDB_FUNC_SCALAR_CONCAT);
assert(numInputs == 2);
assert(pInputs[0].numOfRows >= 1 && pInputs[1].numOfRows >= 1);
assert(pOutput->numOfRows >= MAX(pInputs[0].numOfRows, pInputs[1].numOfRows));
char* data0 = NULL;
char* data1 = NULL;
char* outputData = NULL;
for (int i = 0; i < pOutput->numOfRows; ++i) {
if (pInputs[0].numOfRows == 1 && pInputs[1].numOfRows == 1) {
data0 = pInputs[0].data;
data1 = pInputs[1].data;
} else if (pInputs[0].numOfRows == 1){
data0 = pInputs[0].data;
data1 = pInputs[1].data + i * pInputs[1].bytes;
} else if (pInputs[1].numOfRows == 1){
data0 = pInputs[0].data + i * pInputs[0].bytes;
data1 = pInputs[1].data;
} else {
data0 = pInputs[0].data + i * pInputs[0].bytes;
data1 = pInputs[1].data + i * pInputs[1].bytes;
}
outputData = pOutput->data + i * pOutput->bytes;
if (isNull(data0, pInputs[0].type) || isNull(data1, pInputs[1].type)) {
setNull(outputData, pOutput->type, pOutput->bytes);
} else {
varDataSetLen(outputData, varDataLen(data0)+ varDataLen(data1));
memcpy(varDataVal(outputData), varDataVal(data0), varDataLen(data0));
memcpy(varDataVal(outputData)+ varDataLen(data0), varDataVal(data1), varDataLen(data1));
}
}
}
_expr_scalar_function_t getExprScalarFunction(uint16_t funcId) {
......@@ -956,7 +989,7 @@ tScalarFunctionInfo aScalarFunctions[] = {
},
{
TSDB_FUNC_SCALAR_CONCAT,
"concat",
"strconcat",
vectorConcat
},
};
......@@ -8203,9 +8203,6 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
tfree(pExprs);
return code;
}
type = TSDB_DATA_TYPE_DOUBLE;
bytes = tDataTypes[type].bytes;
} else if (pExprs[i].base.functionId == TSDB_FUNC_BLKINFO) {
SSchema s = {.type=TSDB_DATA_TYPE_BINARY, .bytes=TSDB_MAX_BINARY_LEN};
type = s.type;
......@@ -8266,7 +8263,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
}
// todo remove it
if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].base.resType, &pExprs[i].base.resBytes,
if (pExprs[i].base.functionId != TSDB_FUNC_ARITHM && getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].base.resType, &pExprs[i].base.resBytes,
&pExprs[i].base.interBytes, 0, isSuperTable, pUdfInfo) != TSDB_CODE_SUCCESS) {
tfree(pExprs);
return TSDB_CODE_QRY_INVALID_MSG;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册