未验证 提交 570b36cb 编写于 作者: G Ganlin Zhao 提交者: GitHub

Merge pull request #14232 from taosdata/enh/cast_function

enh(query): enhance cast function to support more types
......@@ -1220,18 +1220,19 @@ static int32_t translateSubstr(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
static int32_t translateCast(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
// The number of parameters has been limited by the syntax definition
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
//uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
// The function return type has been set during syntax parsing
uint8_t para2Type = pFunc->node.resType.type;
if (para2Type != TSDB_DATA_TYPE_BIGINT && para2Type != TSDB_DATA_TYPE_UBIGINT &&
para2Type != TSDB_DATA_TYPE_VARCHAR && para2Type != TSDB_DATA_TYPE_NCHAR &&
para2Type != TSDB_DATA_TYPE_TIMESTAMP) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
if ((para2Type == TSDB_DATA_TYPE_TIMESTAMP && IS_VAR_DATA_TYPE(para1Type)) ||
(para2Type == TSDB_DATA_TYPE_BINARY && para1Type == TSDB_DATA_TYPE_NCHAR)) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
//if (para2Type != TSDB_DATA_TYPE_BIGINT && para2Type != TSDB_DATA_TYPE_UBIGINT &&
// para2Type != TSDB_DATA_TYPE_VARCHAR && para2Type != TSDB_DATA_TYPE_NCHAR &&
// para2Type != TSDB_DATA_TYPE_TIMESTAMP) {
// return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
//}
//if ((para2Type == TSDB_DATA_TYPE_TIMESTAMP && IS_VAR_DATA_TYPE(para1Type)) ||
// (para2Type == TSDB_DATA_TYPE_BINARY && para1Type == TSDB_DATA_TYPE_NCHAR)) {
// return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
//}
int32_t para2Bytes = pFunc->node.resType.bytes;
if (IS_VAR_DATA_TYPE(para2Type)) {
......
......@@ -735,6 +735,60 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
char *input = colDataGetData(pInput[0].columnData, i);
switch(outputType) {
case TSDB_DATA_TYPE_TINYINT: {
if (inputType == TSDB_DATA_TYPE_BINARY) {
*(int8_t *)output = taosStr2Int8(varDataVal(input), NULL, 10);
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
char *newBuf = taosMemoryCalloc(1, inputLen);
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
if (len < 0) {
taosMemoryFree(newBuf);
return TSDB_CODE_FAILED;
}
newBuf[len] = 0;
*(int8_t *)output = taosStr2Int8(newBuf, NULL, 10);
taosMemoryFree(newBuf);
} else {
GET_TYPED_DATA(*(int8_t *)output, int8_t, inputType, input);
}
break;
}
case TSDB_DATA_TYPE_SMALLINT: {
if (inputType == TSDB_DATA_TYPE_BINARY) {
*(int16_t *)output = taosStr2Int16(varDataVal(input), NULL, 10);
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
char *newBuf = taosMemoryCalloc(1, inputLen);
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
if (len < 0) {
taosMemoryFree(newBuf);
return TSDB_CODE_FAILED;
}
newBuf[len] = 0;
*(int16_t *)output = taosStr2Int16(newBuf, NULL, 10);
taosMemoryFree(newBuf);
} else {
GET_TYPED_DATA(*(int16_t *)output, int16_t, inputType, input);
}
break;
}
case TSDB_DATA_TYPE_INT: {
if (inputType == TSDB_DATA_TYPE_BINARY) {
*(int32_t *)output = taosStr2Int32(varDataVal(input), NULL, 10);
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
char *newBuf = taosMemoryCalloc(1, inputLen);
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
if (len < 0) {
taosMemoryFree(newBuf);
return TSDB_CODE_FAILED;
}
newBuf[len] = 0;
*(int32_t *)output = taosStr2Int32(newBuf, NULL, 10);
taosMemoryFree(newBuf);
} else {
GET_TYPED_DATA(*(int32_t *)output, int32_t, inputType, input);
}
break;
}
case TSDB_DATA_TYPE_BIGINT: {
if (inputType == TSDB_DATA_TYPE_BINARY) {
*(int64_t *)output = taosStr2Int64(varDataVal(input), NULL, 10);
......@@ -753,6 +807,60 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
}
break;
}
case TSDB_DATA_TYPE_UTINYINT: {
if (inputType == TSDB_DATA_TYPE_BINARY) {
*(uint8_t *)output = taosStr2UInt8(varDataVal(input), NULL, 10);
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
char *newBuf = taosMemoryCalloc(1, inputLen);
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
if (len < 0) {
taosMemoryFree(newBuf);
return TSDB_CODE_FAILED;
}
newBuf[len] = 0;
*(uint8_t *)output = taosStr2UInt8(newBuf, NULL, 10);
taosMemoryFree(newBuf);
} else {
GET_TYPED_DATA(*(uint8_t *)output, uint8_t, inputType, input);
}
break;
}
case TSDB_DATA_TYPE_USMALLINT: {
if (inputType == TSDB_DATA_TYPE_BINARY) {
*(uint16_t *)output = taosStr2UInt16(varDataVal(input), NULL, 10);
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
char *newBuf = taosMemoryCalloc(1, inputLen);
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
if (len < 0) {
taosMemoryFree(newBuf);
return TSDB_CODE_FAILED;
}
newBuf[len] = 0;
*(uint16_t *)output = taosStr2UInt16(newBuf, NULL, 10);
taosMemoryFree(newBuf);
} else {
GET_TYPED_DATA(*(uint16_t *)output, uint16_t, inputType, input);
}
break;
}
case TSDB_DATA_TYPE_UINT: {
if (inputType == TSDB_DATA_TYPE_BINARY) {
*(uint32_t *)output = taosStr2UInt32(varDataVal(input), NULL, 10);
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
char *newBuf = taosMemoryCalloc(1, inputLen);
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
if (len < 0) {
taosMemoryFree(newBuf);
return TSDB_CODE_FAILED;
}
newBuf[len] = 0;
*(uint32_t *)output = taosStr2UInt32(newBuf, NULL, 10);
taosMemoryFree(newBuf);
} else {
GET_TYPED_DATA(*(uint32_t *)output, uint32_t, inputType, input);
}
break;
}
case TSDB_DATA_TYPE_UBIGINT: {
if (inputType == TSDB_DATA_TYPE_BINARY) {
*(uint64_t *)output = taosStr2UInt64(varDataVal(input), NULL, 10);
......@@ -771,10 +879,64 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
}
break;
}
case TSDB_DATA_TYPE_FLOAT: {
if (inputType == TSDB_DATA_TYPE_BINARY) {
*(float *)output = taosStr2Float(varDataVal(input), NULL);
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
char *newBuf = taosMemoryCalloc(1, inputLen);
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
if (len < 0) {
taosMemoryFree(newBuf);
return TSDB_CODE_FAILED;
}
newBuf[len] = 0;
*(float *)output = taosStr2Float(newBuf, NULL);
taosMemoryFree(newBuf);
} else {
GET_TYPED_DATA(*(float *)output, float, inputType, input);
}
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
if (inputType == TSDB_DATA_TYPE_BINARY) {
*(double *)output = taosStr2Double(varDataVal(input), NULL);
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
char *newBuf = taosMemoryCalloc(1, inputLen);
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
if (len < 0) {
taosMemoryFree(newBuf);
return TSDB_CODE_FAILED;
}
newBuf[len] = 0;
*(double *)output = taosStr2Double(newBuf, NULL);
taosMemoryFree(newBuf);
} else {
GET_TYPED_DATA(*(double *)output, double, inputType, input);
}
break;
}
case TSDB_DATA_TYPE_BOOL: {
if (inputType == TSDB_DATA_TYPE_BINARY) {
*(bool *)output = taosStr2Int8(varDataVal(input), NULL, 10);
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
char *newBuf = taosMemoryCalloc(1, inputLen);
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
if (len < 0) {
taosMemoryFree(newBuf);
return TSDB_CODE_FAILED;
}
newBuf[len] = 0;
*(bool *)output = taosStr2Int8(newBuf, NULL, 10);
taosMemoryFree(newBuf);
} else {
GET_TYPED_DATA(*(bool *)output, bool, inputType, input);
}
break;
}
case TSDB_DATA_TYPE_TIMESTAMP: {
if (inputType == TSDB_DATA_TYPE_BINARY || inputType == TSDB_DATA_TYPE_NCHAR) {
//not support
return TSDB_CODE_FAILED;
//convert to 0
*(int64_t *)output = 0;
} else {
GET_TYPED_DATA(*(int64_t *)output, int64_t, inputType, input);
}
......@@ -789,8 +951,16 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
len = sprintf(varDataVal(output), "%.*s", len, varDataVal(input));
varDataSetLen(output, len);
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
//not support
return TSDB_CODE_FAILED;
char *newBuf = taosMemoryCalloc(1, inputLen);
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
if (len < 0) {
taosMemoryFree(newBuf);
return TSDB_CODE_FAILED;
}
len = TMIN(len, outputLen - VARSTR_HEADER_SIZE);
memcpy(varDataVal(output), newBuf, len);
varDataSetLen(output, len);
taosMemoryFree(newBuf);
} else {
char tmp[400] = {0};
NUM_TO_STRING(inputType, input, sizeof(tmp), tmp);
......
......@@ -630,27 +630,27 @@ class TDTestCase:
( tdSql.checkData(i, 0, '12') for i in range(tdSql.queryRows) )
tdLog.printNoPrefix("==========step40: error cast condition, should return error ")
tdSql.error("select cast(c1 as int) as b from ct4")
tdSql.error("select cast(c1 as bool) as b from ct4")
tdSql.error("select cast(c1 as tinyint) as b from ct4")
tdSql.error("select cast(c1 as smallint) as b from ct4")
tdSql.error("select cast(c1 as float) as b from ct4")
tdSql.error("select cast(c1 as double) as b from ct4")
tdSql.error("select cast(c1 as tinyint unsigned) as b from ct4")
tdSql.error("select cast(c1 as smallint unsigned) as b from ct4")
tdSql.error("select cast(c1 as int unsigned) as b from ct4")
tdSql.error("select cast(c2 as int) as b from ct4")
tdSql.error("select cast(c3 as bool) as b from ct4")
tdSql.error("select cast(c4 as tinyint) as b from ct4")
tdSql.error("select cast(c5 as smallint) as b from ct4")
tdSql.error("select cast(c6 as float) as b from ct4")
tdSql.error("select cast(c7 as double) as b from ct4")
tdSql.error("select cast(c8 as tinyint unsigned) as b from ct4")
tdSql.error("select cast(c8 as timestamp ) as b from ct4")
tdSql.error("select cast(c9 as timestamp ) as b from ct4")
tdSql.error("select cast(c9 as binary(64) ) as b from ct4")
#tdSql.error("select cast(c1 as int) as b from ct4")
#tdSql.error("select cast(c1 as bool) as b from ct4")
#tdSql.error("select cast(c1 as tinyint) as b from ct4")
#tdSql.error("select cast(c1 as smallint) as b from ct4")
#tdSql.error("select cast(c1 as float) as b from ct4")
#tdSql.error("select cast(c1 as double) as b from ct4")
#tdSql.error("select cast(c1 as tinyint unsigned) as b from ct4")
#tdSql.error("select cast(c1 as smallint unsigned) as b from ct4")
#tdSql.error("select cast(c1 as int unsigned) as b from ct4")
#tdSql.error("select cast(c2 as int) as b from ct4")
#tdSql.error("select cast(c3 as bool) as b from ct4")
#tdSql.error("select cast(c4 as tinyint) as b from ct4")
#tdSql.error("select cast(c5 as smallint) as b from ct4")
#tdSql.error("select cast(c6 as float) as b from ct4")
#tdSql.error("select cast(c7 as double) as b from ct4")
#tdSql.error("select cast(c8 as tinyint unsigned) as b from ct4")
#tdSql.error("select cast(c8 as timestamp ) as b from ct4")
#tdSql.error("select cast(c9 as timestamp ) as b from ct4")
#tdSql.error("select cast(c9 as binary(64) ) as b from ct4")
pass
def run(self):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册