Merge pull request #14232 from taosdata/enh/cast_function
enh(query): enhance cast function to support more types
This commit is contained in:
commit
570b36cb9b
|
@ -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) {
|
static int32_t translateCast(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
// The number of parameters has been limited by the syntax definition
|
// 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
|
// The function return type has been set during syntax parsing
|
||||||
uint8_t para2Type = pFunc->node.resType.type;
|
uint8_t para2Type = pFunc->node.resType.type;
|
||||||
if (para2Type != TSDB_DATA_TYPE_BIGINT && para2Type != TSDB_DATA_TYPE_UBIGINT &&
|
//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_VARCHAR && para2Type != TSDB_DATA_TYPE_NCHAR &&
|
||||||
para2Type != TSDB_DATA_TYPE_TIMESTAMP) {
|
// para2Type != TSDB_DATA_TYPE_TIMESTAMP) {
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
// return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
//}
|
||||||
if ((para2Type == TSDB_DATA_TYPE_TIMESTAMP && IS_VAR_DATA_TYPE(para1Type)) ||
|
//if ((para2Type == TSDB_DATA_TYPE_TIMESTAMP && IS_VAR_DATA_TYPE(para1Type)) ||
|
||||||
(para2Type == TSDB_DATA_TYPE_BINARY && para1Type == TSDB_DATA_TYPE_NCHAR)) {
|
// (para2Type == TSDB_DATA_TYPE_BINARY && para1Type == TSDB_DATA_TYPE_NCHAR)) {
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
// return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
//}
|
||||||
|
|
||||||
int32_t para2Bytes = pFunc->node.resType.bytes;
|
int32_t para2Bytes = pFunc->node.resType.bytes;
|
||||||
if (IS_VAR_DATA_TYPE(para2Type)) {
|
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);
|
char *input = colDataGetData(pInput[0].columnData, i);
|
||||||
|
|
||||||
switch(outputType) {
|
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: {
|
case TSDB_DATA_TYPE_BIGINT: {
|
||||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||||
*(int64_t *)output = taosStr2Int64(varDataVal(input), NULL, 10);
|
*(int64_t *)output = taosStr2Int64(varDataVal(input), NULL, 10);
|
||||||
|
@ -753,6 +807,60 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
|
||||||
}
|
}
|
||||||
break;
|
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: {
|
case TSDB_DATA_TYPE_UBIGINT: {
|
||||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||||
*(uint64_t *)output = taosStr2UInt64(varDataVal(input), NULL, 10);
|
*(uint64_t *)output = taosStr2UInt64(varDataVal(input), NULL, 10);
|
||||||
|
@ -771,10 +879,64 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
|
||||||
}
|
}
|
||||||
break;
|
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: {
|
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||||
if (inputType == TSDB_DATA_TYPE_BINARY || inputType == TSDB_DATA_TYPE_NCHAR) {
|
if (inputType == TSDB_DATA_TYPE_BINARY || inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||||
//not support
|
//convert to 0
|
||||||
return TSDB_CODE_FAILED;
|
*(int64_t *)output = 0;
|
||||||
} else {
|
} else {
|
||||||
GET_TYPED_DATA(*(int64_t *)output, int64_t, inputType, input);
|
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));
|
len = sprintf(varDataVal(output), "%.*s", len, varDataVal(input));
|
||||||
varDataSetLen(output, len);
|
varDataSetLen(output, len);
|
||||||
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||||
//not support
|
char *newBuf = taosMemoryCalloc(1, inputLen);
|
||||||
return TSDB_CODE_FAILED;
|
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 {
|
} else {
|
||||||
char tmp[400] = {0};
|
char tmp[400] = {0};
|
||||||
NUM_TO_STRING(inputType, input, sizeof(tmp), tmp);
|
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) )
|
( tdSql.checkData(i, 0, '12') for i in range(tdSql.queryRows) )
|
||||||
|
|
||||||
tdLog.printNoPrefix("==========step40: error cast condition, should return error ")
|
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 int) as b from ct4")
|
||||||
tdSql.error("select cast(c1 as bool) 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 tinyint) as b from ct4")
|
||||||
tdSql.error("select cast(c1 as smallint) 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 float) as b from ct4")
|
||||||
tdSql.error("select cast(c1 as double) 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 tinyint unsigned) as b from ct4")
|
||||||
tdSql.error("select cast(c1 as smallint 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(c1 as int unsigned) as b from ct4")
|
||||||
|
|
||||||
tdSql.error("select cast(c2 as int) 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(c3 as bool) as b from ct4")
|
||||||
tdSql.error("select cast(c4 as tinyint) 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(c5 as smallint) as b from ct4")
|
||||||
tdSql.error("select cast(c6 as float) 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(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 tinyint unsigned) as b from ct4")
|
||||||
|
|
||||||
tdSql.error("select cast(c8 as timestamp ) 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 timestamp ) as b from ct4")
|
||||||
tdSql.error("select cast(c9 as binary(64) ) as b from ct4")
|
#tdSql.error("select cast(c9 as binary(64) ) as b from ct4")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
|
Loading…
Reference in New Issue