Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
838e5667
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
838e5667
编写于
11月 22, 2021
作者:
D
dapan1121
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
cast
上级
5f3b91d6
变更
12
展开全部
显示空白变更内容
内联
并排
Showing
12 changed file
with
1209 addition
and
470 deletion
+1209
-470
src/client/src/tscSQLParser.c
src/client/src/tscSQLParser.c
+15
-2
src/common/inc/texpr.h
src/common/inc/texpr.h
+7
-3
src/common/src/texpr.c
src/common/src/texpr.c
+171
-13
src/inc/ttokendef.h
src/inc/ttokendef.h
+2
-0
src/inc/ttype.h
src/inc/ttype.h
+36
-0
src/query/inc/qAggMain.h
src/query/inc/qAggMain.h
+1
-1
src/query/inc/qSqlparser.h
src/query/inc/qSqlparser.h
+3
-0
src/query/inc/sql.y
src/query/inc/sql.y
+3
-0
src/query/src/qAggMain.c
src/query/src/qAggMain.c
+2
-2
src/query/src/qSqlParser.c
src/query/src/qSqlParser.c
+27
-0
src/query/src/sql.c
src/query/src/sql.c
+463
-449
tests/script/general/compute/cast.sim
tests/script/general/compute/cast.sim
+479
-0
未找到文件。
src/client/src/tscSQLParser.c
浏览文件 @
838e5667
...
...
@@ -1781,7 +1781,7 @@ static int32_t handleScalarTypeExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32
}
}
ret
=
exprTreeValidateTree
(
pNode
);
ret
=
exprTreeValidateTree
(
tscGetErrorMsgPayload
(
pCmd
),
pNode
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
taosArrayDestroy
(
colList
);
tExprTreeDestroy
(
pNode
,
NULL
);
...
...
@@ -1845,7 +1845,7 @@ static int32_t handleAggTypeExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t
return
invalidOperationMsg
(
tscGetErrorMsgPayload
(
pCmd
),
"invalid expression in select clause"
);
}
ret
=
exprTreeValidateTree
(
pExpr
);
ret
=
exprTreeValidateTree
(
tscGetErrorMsgPayload
(
pCmd
),
pExpr
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
tExprTreeDestroy
(
pExpr
,
NULL
);
return
invalidOperationMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg2
);
...
...
@@ -4455,6 +4455,11 @@ static int32_t validateSQLExprItem(SSqlCmd* pCmd, tSqlExpr* pExpr,
pList
->
ids
[
pList
->
num
++
]
=
index
;
*
type
=
SQLEXPR_TYPE_SCALAR
;
}
else
if
(
pExpr
->
type
==
SQL_NODE_DATA_TYPE
)
{
if
(
pExpr
->
dataType
.
type
<
0
||
pExpr
->
dataType
.
bytes
<=
0
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
*
type
=
SQLEXPR_TYPE_SCALAR
;
}
else
{
if
((
pExpr
->
tokenId
==
TK_FLOAT
&&
(
isnan
(
pExpr
->
value
.
dKey
)
||
isinf
(
pExpr
->
value
.
dKey
)))
||
pExpr
->
tokenId
==
TK_NULL
)
{
...
...
@@ -9489,6 +9494,14 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
taosArrayPush
(
pCols
,
&
colIndex
);
}
return
TSDB_CODE_SUCCESS
;
}
else
if
(
pSqlExpr
->
type
==
SQL_NODE_DATA_TYPE
)
{
*
pExpr
=
calloc
(
1
,
sizeof
(
tExprNode
));
(
*
pExpr
)
->
nodeType
=
TSQL_NODE_TYPE
;
(
*
pExpr
)
->
pType
=
calloc
(
1
,
sizeof
(
TAOS_FIELD
));
*
(
*
pExpr
)
->
pType
=
pSqlExpr
->
dataType
;
return
TSDB_CODE_SUCCESS
;
}
else
if
(
pSqlExpr
->
tokenId
==
TK_SET
)
{
int32_t
colType
=
-
1
;
...
...
src/common/inc/texpr.h
浏览文件 @
838e5667
...
...
@@ -62,7 +62,8 @@ struct SSchema;
#define TSDB_FUNC_SCALAR_ROUND (TSDB_FUNC_FLAG_SCALAR | 0x000C)
#define TSDB_FUNC_SCALAR_CONCAT (TSDB_FUNC_FLAG_SCALAR | 0x000D)
#define TSDB_FUNC_SCALAR_LENGTH (TSDB_FUNC_FLAG_SCALAR | 0x000E)
#define TSDB_FUNC_SCALAR_MAX_NUM 15
#define TSDB_FUNC_SCALAR_CAST (TSDB_FUNC_FLAG_SCALAR | 0x000F)
#define TSDB_FUNC_SCALAR_MAX_NUM 16
#define TSDB_FUNC_SCALAR_NAME_MAX_LEN 16
...
...
@@ -95,7 +96,8 @@ enum {
TSQL_NODE_EXPR
=
0x1
,
TSQL_NODE_COL
=
0x2
,
TSQL_NODE_VALUE
=
0x4
,
TSQL_NODE_FUNC
=
0x8
TSQL_NODE_FUNC
=
0x8
,
TSQL_NODE_TYPE
=
0x10
};
/**
...
...
@@ -129,6 +131,8 @@ typedef struct tExprNode {
uint8_t
numChildren
;
struct
tExprNode
**
pChildren
;
}
_func
;
TAOS_FIELD
*
pType
;
};
int16_t
resultType
;
int16_t
resultBytes
;
...
...
@@ -142,7 +146,7 @@ typedef struct SExprTraverseSupp {
void
tExprTreeDestroy
(
tExprNode
*
pNode
,
void
(
*
fp
)(
void
*
));
int32_t
exprTreeValidateTree
(
tExprNode
*
pExpr
);
int32_t
exprTreeValidateTree
(
char
*
msgbuf
,
tExprNode
*
pExpr
);
void
exprTreeToBinary
(
SBufferWriter
*
bw
,
tExprNode
*
pExprTree
);
tExprNode
*
exprTreeFromBinary
(
const
void
*
data
,
size_t
size
);
...
...
src/common/src/texpr.c
浏览文件 @
838e5667
...
...
@@ -31,8 +31,19 @@
static
int32_t
exprValidateMathNode
(
tExprNode
*
pExpr
);
static
int32_t
exprValidateStringConcatNode
(
tExprNode
*
pExpr
);
static
int32_t
exprValidateStringLengthNode
(
tExprNode
*
pExpr
);
static
int32_t
exprValidateCastNode
(
char
*
msgbuf
,
tExprNode
*
pExpr
);
int32_t
exprTreeValidateFunctionNode
(
tExprNode
*
pExpr
)
{
static
int32_t
exprInvalidOperationMsg
(
char
*
msgbuf
,
const
char
*
msg
)
{
const
char
*
msgFormat
=
"invalid operation: %s"
;
sprintf
(
msgbuf
,
msgFormat
,
msg
);
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
int32_t
exprTreeValidateFunctionNode
(
char
*
msgbuf
,
tExprNode
*
pExpr
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
//TODO: check childs for every function
switch
(
pExpr
->
_func
.
functionId
)
{
...
...
@@ -57,7 +68,9 @@ int32_t exprTreeValidateFunctionNode(tExprNode *pExpr) {
case
TSDB_FUNC_SCALAR_LENGTH
:
{
return
exprValidateStringLengthNode
(
pExpr
);
}
case
TSDB_FUNC_SCALAR_CAST
:
{
return
exprValidateCastNode
(
msgbuf
,
pExpr
);
}
default:
break
;
}
...
...
@@ -81,7 +94,7 @@ int32_t exprTreeValidateExprNode(tExprNode *pExpr) {
}
}
int32_t
exprTreeValidateTree
(
tExprNode
*
pExpr
)
{
int32_t
exprTreeValidateTree
(
char
*
msgbuf
,
tExprNode
*
pExpr
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
(
pExpr
==
NULL
)
{
return
TSDB_CODE_SUCCESS
;
...
...
@@ -101,11 +114,11 @@ int32_t exprTreeValidateTree(tExprNode *pExpr) {
pExpr
->
resultBytes
=
tGetTbnameColumnSchema
()
->
bytes
;
}
}
else
if
(
pExpr
->
nodeType
==
TSQL_NODE_EXPR
)
{
code
=
exprTreeValidateTree
(
pExpr
->
_node
.
pLeft
);
code
=
exprTreeValidateTree
(
msgbuf
,
pExpr
->
_node
.
pLeft
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
code
=
exprTreeValidateTree
(
pExpr
->
_node
.
pRight
);
code
=
exprTreeValidateTree
(
msgbuf
,
pExpr
->
_node
.
pRight
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
...
...
@@ -115,15 +128,18 @@ int32_t exprTreeValidateTree(tExprNode *pExpr) {
}
}
else
if
(
pExpr
->
nodeType
==
TSQL_NODE_FUNC
)
{
for
(
int32_t
i
=
0
;
i
<
pExpr
->
_func
.
numChildren
;
++
i
)
{
code
=
exprTreeValidateTree
(
pExpr
->
_func
.
pChildren
[
i
]);
code
=
exprTreeValidateTree
(
msgbuf
,
pExpr
->
_func
.
pChildren
[
i
]);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
code
=
exprTreeValidateFunctionNode
(
pExpr
);
code
=
exprTreeValidateFunctionNode
(
msgbuf
,
pExpr
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
else
if
(
pExpr
->
nodeType
==
TSQL_NODE_TYPE
)
{
pExpr
->
resultType
=
pExpr
->
pType
->
type
;
pExpr
->
resultBytes
=
pExpr
->
pType
->
bytes
;
}
return
TSDB_CODE_SUCCESS
;
...
...
@@ -222,6 +238,8 @@ void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *)) {
tfree
(
pNode
->
pSchema
);
}
else
if
(
pNode
->
nodeType
==
TSQL_NODE_FUNC
)
{
doExprTreeDestroy
(
&
pNode
,
fp
);
}
else
if
(
pNode
->
nodeType
==
TSQL_NODE_TYPE
)
{
tfree
(
pNode
->
pType
);
}
free
(
pNode
);
...
...
@@ -249,6 +267,8 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
doExprTreeDestroy
((
*
pExpr
)
->
_func
.
pChildren
+
i
,
fp
);
}
free
((
*
pExpr
)
->
_func
.
pChildren
);
}
else
if
((
*
pExpr
)
->
nodeType
==
TSQL_NODE_TYPE
)
{
tfree
((
*
pExpr
)
->
pType
);
}
free
(
*
pExpr
);
...
...
@@ -344,7 +364,7 @@ void exprTreeFunctionNodeTraverse(tExprNode *pExpr, int32_t numOfRows, tExprOper
for
(
int
i
=
0
;
i
<
numChildren
;
++
i
)
{
tExprNode
*
pChild
=
pExpr
->
_func
.
pChildren
[
i
];
if
(
pChild
->
nodeType
==
TSQL_NODE_EXPR
||
pChild
->
nodeType
==
TSQL_NODE_FUNC
)
{
pChildrenOutput
[
i
]
=
malloc
(
pChild
->
resultBytes
*
numOfRows
);
pChildrenOutput
[
i
]
=
malloc
(
(
pChild
->
resultBytes
+
1
)
*
numOfRows
);
pChildrenResults
[
i
].
data
=
pChildrenOutput
[
i
];
exprTreeInternalNodeTraverse
(
pChild
,
numOfRows
,
pChildrenResults
+
i
,
param
,
order
,
getSourceDataBlock
);
pInputs
[
i
].
data
=
pChildrenOutput
[
i
];
...
...
@@ -353,7 +373,7 @@ void exprTreeFunctionNodeTraverse(tExprNode *pExpr, int32_t numOfRows, tExprOper
assert
(
pChild
->
resultType
==
pChild
->
pSchema
->
type
&&
pChild
->
resultBytes
==
pChild
->
pSchema
->
bytes
);
char
*
pInputData
=
getSourceDataBlock
(
param
,
pChild
->
pSchema
->
name
,
pChild
->
pSchema
->
colId
);
if
(
order
==
TSDB_ORDER_DESC
)
{
pChildrenOutput
[
i
]
=
malloc
(
pChild
->
pSchema
->
bytes
*
numOfRows
);
pChildrenOutput
[
i
]
=
malloc
(
(
pChild
->
pSchema
->
bytes
+
1
)
*
numOfRows
);
reverseCopy
(
pChildrenOutput
[
i
],
pInputData
,
pChild
->
pSchema
->
type
,
numOfRows
);
pInputs
[
i
].
data
=
pChildrenOutput
[
i
];
}
else
{
...
...
@@ -361,7 +381,7 @@ void exprTreeFunctionNodeTraverse(tExprNode *pExpr, int32_t numOfRows, tExprOper
}
pInputs
[
i
].
numOfRows
=
(
int16_t
)
numOfRows
;
}
else
if
(
pChild
->
nodeType
==
TSQL_NODE_VALUE
)
{
pChildrenOutput
[
i
]
=
malloc
(
pChild
->
resultBytes
);
pChildrenOutput
[
i
]
=
malloc
(
pChild
->
resultBytes
+
1
);
tVariantDump
(
pChild
->
pVal
,
pChildrenOutput
[
i
],
pChild
->
resultType
,
true
);
pInputs
[
i
].
data
=
pChildrenOutput
[
i
];
pInputs
[
i
].
numOfRows
=
1
;
...
...
@@ -860,6 +880,9 @@ tExprNode* exprdup(tExprNode* pNode) {
for
(
int
i
=
0
;
i
<
pNode
->
_func
.
numChildren
;
++
i
)
{
pCloned
->
_func
.
pChildren
[
i
]
=
exprdup
(
pNode
->
_func
.
pChildren
[
i
]);
}
}
else
if
(
pNode
->
nodeType
==
TSQL_NODE_TYPE
)
{
pCloned
->
pType
=
calloc
(
1
,
sizeof
(
TAOS_FIELD
));
*
pCloned
->
pType
=
*
pNode
->
pType
;
}
pCloned
->
nodeType
=
pNode
->
nodeType
;
...
...
@@ -964,6 +987,45 @@ int32_t exprValidateStringLengthNode(tExprNode *pExpr) {
return
TSDB_CODE_SUCCESS
;
}
int32_t
exprValidateCastNode
(
char
*
msgbuf
,
tExprNode
*
pExpr
)
{
const
char
*
msg1
=
"invalid param num for cast function"
;
const
char
*
msg2
=
"the second param should be a valid type name for cast function"
;
const
char
*
msg3
=
"target type is not supported for cast function"
;
const
char
*
msg4
=
"not supported type convertion for cast function"
;
if
(
pExpr
->
_func
.
numChildren
!=
2
)
{
return
exprInvalidOperationMsg
(
msgbuf
,
msg1
);
}
tExprNode
*
child0
=
pExpr
->
_func
.
pChildren
[
0
];
tExprNode
*
child1
=
pExpr
->
_func
.
pChildren
[
1
];
if
(
child1
->
nodeType
!=
TSQL_NODE_TYPE
)
{
return
exprInvalidOperationMsg
(
msgbuf
,
msg2
);
}
if
(
child1
->
resultType
!=
TSDB_DATA_TYPE_BIGINT
&&
child1
->
resultType
!=
TSDB_DATA_TYPE_UBIGINT
&&
child1
->
resultType
!=
TSDB_DATA_TYPE_TIMESTAMP
&&
child1
->
resultType
!=
TSDB_DATA_TYPE_BINARY
&&
child1
->
resultType
!=
TSDB_DATA_TYPE_NCHAR
)
{
return
exprInvalidOperationMsg
(
msgbuf
,
msg3
);
}
if
((
child0
->
resultType
==
TSDB_DATA_TYPE_BINARY
&&
child1
->
resultType
==
TSDB_DATA_TYPE_TIMESTAMP
)
||
(
child0
->
resultType
==
TSDB_DATA_TYPE_TIMESTAMP
&&
(
child1
->
resultType
==
TSDB_DATA_TYPE_BINARY
||
child1
->
resultType
==
TSDB_DATA_TYPE_NCHAR
))
||
(
child0
->
resultType
==
TSDB_DATA_TYPE_NCHAR
&&
(
child1
->
resultType
==
TSDB_DATA_TYPE_BINARY
||
child1
->
resultType
==
TSDB_DATA_TYPE_TIMESTAMP
)))
{
return
exprInvalidOperationMsg
(
msgbuf
,
msg4
);
}
pExpr
->
resultType
=
child1
->
resultType
;
pExpr
->
resultBytes
=
child1
->
resultBytes
;
doExprTreeDestroy
(
&
pExpr
->
_func
.
pChildren
[
1
],
NULL
);
pExpr
->
_func
.
numChildren
=
1
;
return
TSDB_CODE_SUCCESS
;
}
int32_t
exprValidateMathNode
(
tExprNode
*
pExpr
)
{
switch
(
pExpr
->
_func
.
functionId
)
{
case
TSDB_FUNC_SCALAR_POW
:
...
...
@@ -1102,6 +1164,93 @@ void vectorLength(int16_t functionId, tExprOperandInfo *pInputs, uint8_t numInpu
}
}
void
castConvert
(
int16_t
inputType
,
int16_t
inputBytes
,
char
*
input
,
int16_t
OutputType
,
int16_t
outputBytes
,
char
*
output
)
{
switch
(
OutputType
)
{
case
TSDB_DATA_TYPE_BIGINT
:
if
(
inputType
==
TSDB_DATA_TYPE_BINARY
)
{
input
[
inputBytes
]
=
0
;
*
(
int64_t
*
)
output
=
strtoll
(
varDataVal
(
input
),
NULL
,
10
);
}
else
if
(
inputType
==
TSDB_DATA_TYPE_NCHAR
)
{
char
*
newColData
=
calloc
(
1
,
outputBytes
*
TSDB_NCHAR_SIZE
+
1
);
int
len
=
taosUcs4ToMbs
(
varDataVal
(
input
),
varDataLen
(
input
),
newColData
);
newColData
[
len
]
=
0
;
*
(
int64_t
*
)
output
=
strtoll
(
newColData
,
NULL
,
10
);
tfree
(
newColData
);
}
else
{
GET_TYPED_DATA
(
*
(
int64_t
*
)
output
,
int64_t
,
inputType
,
input
);
}
break
;
case
TSDB_DATA_TYPE_UBIGINT
:
if
(
inputType
==
TSDB_DATA_TYPE_BINARY
)
{
input
[
inputBytes
]
=
0
;
*
(
uint64_t
*
)
output
=
strtoull
(
varDataVal
(
input
),
NULL
,
10
);
}
else
if
(
inputType
==
TSDB_DATA_TYPE_NCHAR
)
{
char
*
newColData
=
calloc
(
1
,
outputBytes
*
TSDB_NCHAR_SIZE
+
1
);
int
len
=
taosUcs4ToMbs
(
varDataVal
(
input
),
varDataLen
(
input
),
newColData
);
newColData
[
len
]
=
0
;
*
(
int64_t
*
)
output
=
strtoull
(
newColData
,
NULL
,
10
);
tfree
(
newColData
);
}
else
{
GET_TYPED_DATA
(
*
(
uint64_t
*
)
output
,
uint64_t
,
inputType
,
input
);
}
break
;
case
TSDB_DATA_TYPE_TIMESTAMP
:
if
(
inputType
==
TSDB_DATA_TYPE_BINARY
||
inputType
==
TSDB_DATA_TYPE_NCHAR
)
{
assert
(
0
);
}
else
{
GET_TYPED_DATA
(
*
(
int64_t
*
)
output
,
int64_t
,
inputType
,
input
);
}
break
;
case
TSDB_DATA_TYPE_BINARY
:
if
(
inputType
==
TSDB_DATA_TYPE_BOOL
)
{
int32_t
len
=
sprintf
(
varDataVal
(
output
),
"%.*s"
,
(
int32_t
)(
outputBytes
-
VARSTR_HEADER_SIZE
),
*
(
int8_t
*
)
input
?
"true"
:
"false"
);
varDataSetLen
(
output
,
len
);
}
else
if
(
inputType
==
TSDB_DATA_TYPE_BINARY
)
{
int32_t
len
=
sprintf
(
varDataVal
(
output
),
"%.*s"
,
(
int32_t
)(
outputBytes
-
VARSTR_HEADER_SIZE
),
input
);
varDataSetLen
(
output
,
len
);
}
else
if
(
inputType
==
TSDB_DATA_TYPE_TIMESTAMP
||
inputType
==
TSDB_DATA_TYPE_NCHAR
)
{
assert
(
0
);
}
else
{
char
tmp
[
64
]
=
{
0
};
NUM_TO_STRING
(
inputType
,
input
,
sizeof
(
tmp
),
tmp
);
int32_t
len
=
strlen
(
tmp
);
len
=
(
outputBytes
-
VARSTR_HEADER_SIZE
)
>
len
?
len
:
(
outputBytes
-
VARSTR_HEADER_SIZE
);
memcpy
(
varDataVal
(
output
),
tmp
,
len
);
varDataSetLen
(
output
,
len
);
}
break
;
case
TSDB_DATA_TYPE_NCHAR
:
{
int32_t
ncharSize
=
(
outputBytes
-
VARSTR_HEADER_SIZE
)
/
TSDB_NCHAR_SIZE
;
if
(
inputType
==
TSDB_DATA_TYPE_BOOL
)
{
char
tmp
[
8
]
=
{
0
};
int32_t
len
=
sprintf
(
tmp
,
"%.*s"
,
ncharSize
,
*
(
int8_t
*
)
input
?
"true"
:
"false"
);
taosMbsToUcs4
(
tmp
,
len
,
varDataVal
(
output
),
outputBytes
-
VARSTR_HEADER_SIZE
,
&
len
);
varDataSetLen
(
output
,
len
);
}
else
if
(
inputType
==
TSDB_DATA_TYPE_BINARY
)
{
int32_t
len
=
ncharSize
>
varDataLen
(
input
)
?
varDataLen
(
input
)
:
ncharSize
;
taosMbsToUcs4
(
input
+
VARSTR_HEADER_SIZE
,
len
,
varDataVal
(
output
),
outputBytes
-
VARSTR_HEADER_SIZE
,
&
len
);
varDataSetLen
(
output
,
len
);
}
else
if
(
inputType
==
TSDB_DATA_TYPE_TIMESTAMP
)
{
assert
(
0
);
}
else
if
(
inputType
==
TSDB_DATA_TYPE_NCHAR
)
{
int32_t
len
=
(
inputBytes
>
outputBytes
)
?
outputBytes
:
inputBytes
;
memcpy
(
output
,
input
,
len
);
varDataSetLen
(
output
,
len
-
VARSTR_HEADER_SIZE
);
}
else
{
char
tmp
[
64
]
=
{
0
};
NUM_TO_STRING
(
inputType
,
input
,
sizeof
(
tmp
),
tmp
);
int32_t
len
=
ncharSize
>
strlen
(
tmp
)
?
strlen
(
tmp
)
:
ncharSize
;
taosMbsToUcs4
(
tmp
,
len
,
varDataVal
(
output
),
outputBytes
-
VARSTR_HEADER_SIZE
,
&
len
);
varDataSetLen
(
output
,
len
);
}
break
;
}
default:
assert
(
0
);
break
;
}
}
void
vectorMathFunc
(
int16_t
functionId
,
tExprOperandInfo
*
pInputs
,
uint8_t
numInputs
,
tExprOperandInfo
*
pOutput
,
int32_t
order
)
{
for
(
int
i
=
0
;
i
<
numInputs
;
++
i
)
{
...
...
@@ -1306,6 +1455,10 @@ void vectorMathFunc(int16_t functionId, tExprOperandInfo *pInputs, uint8_t numIn
}
break
;
}
case
TSDB_FUNC_SCALAR_CAST
:
{
castConvert
(
pInputs
[
0
].
type
,
pInputs
[
0
].
bytes
,
inputData
[
0
],
pOutput
->
type
,
pOutput
->
bytes
,
outputData
);
break
;
}
default:
{
assert
(
false
);
break
;
...
...
@@ -1398,5 +1551,10 @@ tScalarFunctionInfo aScalarFunctions[] = {
TSDB_FUNC_SCALAR_LENGTH
,
"length"
,
vectorLength
}
},
{
TSDB_FUNC_SCALAR_CAST
,
"cast"
,
vectorMathFunc
},
};
src/inc/ttokendef.h
浏览文件 @
838e5667
...
...
@@ -217,6 +217,8 @@
#define TK_SPACE 300
#define TK_COMMENT 301
#define TK_ILLEGAL 302
...
...
src/inc/ttype.h
浏览文件 @
838e5667
...
...
@@ -125,6 +125,42 @@ typedef struct {
} \
} while (0)
#define NUM_TO_STRING(_inputType, _input, _outputBytes, _output) \
do { \
switch (_inputType) { \
case TSDB_DATA_TYPE_TINYINT: \
snprintf(_output, (int32_t)(_outputBytes), "%d", *(int8_t *)(_input)); \
break; \
case TSDB_DATA_TYPE_UTINYINT: \
snprintf(_output, (int32_t)(_outputBytes), "%d", *(uint8_t *)(_input)); \
break; \
case TSDB_DATA_TYPE_SMALLINT: \
snprintf(_output, (int32_t)(_outputBytes), "%d", *(int16_t *)(_input)); \
break; \
case TSDB_DATA_TYPE_USMALLINT: \
snprintf(_output, (int32_t)(_outputBytes), "%d", *(uint16_t *)(_input)); \
break; \
case TSDB_DATA_TYPE_BIGINT: \
snprintf(_output, (int32_t)(_outputBytes), "%" PRId64, *(int64_t *)(_input)); \
break; \
case TSDB_DATA_TYPE_UBIGINT: \
snprintf(_output, (int32_t)(_outputBytes), "%" PRIu64, *(uint64_t *)(_input)); \
break; \
case TSDB_DATA_TYPE_FLOAT: \
snprintf(_output, (int32_t)(_outputBytes), "%e", *(float *)(_input)); \
break; \
case TSDB_DATA_TYPE_DOUBLE: \
snprintf(_output, (int32_t)(_outputBytes), "%e", *(double *)(_input)); \
break; \
case TSDB_DATA_TYPE_UINT: \
snprintf(_output, (int32_t)(_outputBytes), "%u", *(uint32_t *)(_input)); \
break; \
default: \
snprintf(_output, (int32_t)(_outputBytes), "%d", *(int32_t *)(_input)); \
break; \
} \
} while (0)
#define IS_SIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_TINYINT && (_t) <= TSDB_DATA_TYPE_BIGINT)
#define IS_UNSIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_UTINYINT && (_t) <= TSDB_DATA_TYPE_UBIGINT)
#define IS_FLOAT_TYPE(_t) ((_t) == TSDB_DATA_TYPE_FLOAT || (_t) == TSDB_DATA_TYPE_DOUBLE)
...
...
src/query/inc/qAggMain.h
浏览文件 @
838e5667
...
...
@@ -252,7 +252,7 @@ void blockDistInfoToBinary(STableBlockDist* pDist, struct SBufferWriter* bw);
void
blockDistInfoFromBinary
(
const
char
*
data
,
int32_t
len
,
STableBlockDist
*
pDist
);
/* global sql function array */
extern
struct
SAggFunctionInfo
aAggs
[];
extern
struct
SAggFunctionInfo
aAggs
[
40
];
extern
int32_t
functionCompatList
[];
// compatible check array list
...
...
src/query/inc/qSqlparser.h
浏览文件 @
838e5667
...
...
@@ -38,6 +38,7 @@ enum SQL_NODE_TYPE {
SQL_NODE_SQLFUNCTION
=
2
,
SQL_NODE_VALUE
=
3
,
SQL_NODE_EXPR
=
4
,
SQL_NODE_DATA_TYPE
=
5
,
};
enum
SQL_NODE_FROM_TYPE
{
...
...
@@ -258,6 +259,7 @@ typedef struct tSqlExpr {
int32_t
functionId
;
// function id, todo remove it
SStrToken
columnName
;
// table column info
TAOS_FIELD
dataType
;
// data type
tVariant
value
;
// the use input value
SStrToken
exprToken
;
// original sql expr string
uint32_t
flags
;
// todo remove it
...
...
@@ -284,6 +286,7 @@ SRelationInfo *addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrT
// sql expr leaf node
tSqlExpr
*
tSqlExprCreateIdValue
(
SSqlInfo
*
pInfo
,
SStrToken
*
pToken
,
int32_t
optrType
);
tSqlExpr
*
tSqlExprCreateFunction
(
SArray
*
pParam
,
SStrToken
*
pFuncToken
,
SStrToken
*
endToken
,
int32_t
optType
);
tSqlExpr
*
tSqlExprCreateFuncWithParams
(
SSqlInfo
*
pInfo
,
tSqlExpr
*
col
,
TAOS_FIELD
*
colType
,
SStrToken
*
pFuncToken
,
SStrToken
*
endToken
,
int32_t
optType
);
SArray
*
tStrTokenAppend
(
SArray
*
pList
,
SStrToken
*
pToken
);
tSqlExpr
*
tSqlExprCreate
(
tSqlExpr
*
pLeft
,
tSqlExpr
*
pRight
,
int32_t
optrType
);
...
...
src/query/inc/sql.y
浏览文件 @
838e5667
...
...
@@ -723,6 +723,9 @@ expr(A) ::= ID(X) LP exprlist(Y) RP(E). { tStrTokenAppend(pInfo->funcs, &X); A =
// for parsing sql functions with wildcard for parameters. e.g., count(*)/first(*)/last(*) operation
expr(A) ::= ID(X) LP STAR RP(Y). { tStrTokenAppend(pInfo->funcs, &X); A = tSqlExprCreateFunction(NULL, &X, &Y, X.type); }
// for parsing sql function CAST(column as typename)
expr(A) ::= ID(X) LP expr(B) AS typename(C) RP(Y). { tStrTokenAppend(pInfo->funcs, &X); A = tSqlExprCreateFuncWithParams(pInfo, B, &C, &X, &Y, X.type); }
// is (not) null expression
expr(A) ::= expr(X) IS NULL. {A = tSqlExprCreate(X, NULL, TK_ISNULL);}
expr(A) ::= expr(X) IS NOT NULL. {A = tSqlExprCreate(X, NULL, TK_NOTNULL);}
...
...
src/query/src/qAggMain.c
浏览文件 @
838e5667
...
...
@@ -480,7 +480,7 @@ int32_t isValidFunction(const char* name, int32_t len) {
}
}
for
(
int32_t
i
=
0
;
i
<=
TSDB_FUNC_BLKINFO
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<=
tListLen
(
aAggs
)
;
++
i
)
{
int32_t
nameLen
=
(
int32_t
)
strlen
(
aAggs
[
i
].
name
);
if
(
len
!=
nameLen
)
{
continue
;
...
...
@@ -4852,7 +4852,7 @@ int32_t functionCompatList[] = {
7
};
SAggFunctionInfo
aAggs
[]
=
{{
SAggFunctionInfo
aAggs
[
40
]
=
{{
// 0, count function does not invoke the finalize function
"count"
,
TSDB_FUNC_COUNT
,
...
...
src/query/src/qSqlParser.c
浏览文件 @
838e5667
...
...
@@ -178,6 +178,14 @@ tSqlExpr *tSqlExprCreateIdValue(SSqlInfo* pInfo, SStrToken *pToken, int32_t optr
pSqlExpr
->
value
.
nType
=
TSDB_DATA_TYPE_BIGINT
;
pSqlExpr
->
tokenId
=
TK_TIMESTAMP
;
pSqlExpr
->
type
=
SQL_NODE_VALUE
;
}
else
if
(
optrType
==
TK_AS
)
{
// Here it must be column type
if
(
pToken
!=
NULL
)
{
pSqlExpr
->
dataType
=
*
(
TAOS_FIELD
*
)
pToken
;
}
pSqlExpr
->
tokenId
=
optrType
;
pSqlExpr
->
type
=
SQL_NODE_DATA_TYPE
;
}
else
{
// Here it must be the column name (tk_id) if it is not a number or string.
assert
(
optrType
==
TK_ID
||
optrType
==
TK_ALL
);
...
...
@@ -216,6 +224,25 @@ tSqlExpr *tSqlExprCreateFunction(SArray *pParam, SStrToken *pFuncToken, SStrToke
return
pExpr
;
}
tSqlExpr
*
tSqlExprCreateFuncWithParams
(
SSqlInfo
*
pInfo
,
tSqlExpr
*
col
,
TAOS_FIELD
*
colType
,
SStrToken
*
pFuncToken
,
SStrToken
*
endToken
,
int32_t
optType
)
{
if
(
colType
==
NULL
||
col
==
NULL
)
{
return
NULL
;
}
if
(
NULL
==
col
)
{
return
NULL
;
}
tSqlExpr
*
ctype
=
tSqlExprCreateIdValue
(
pInfo
,
(
SStrToken
*
)
colType
,
TK_AS
);
SArray
*
exprList
=
tSqlExprListAppend
(
0
,
col
,
0
,
0
);
tSqlExprListAppend
(
exprList
,
ctype
,
0
,
0
);
return
tSqlExprCreateFunction
(
exprList
,
pFuncToken
,
endToken
,
optType
);
}
/*
* create binary expression in this procedure
* if the expr is arithmetic, calculate the result and set it to tSqlExpr Object
...
...
src/query/src/sql.c
浏览文件 @
838e5667
此差异已折叠。
点击以展开。
tests/script/general/compute/cast.sim
0 → 100644
浏览文件 @
838e5667
system sh/stop_dnodes.sh
system sh/deploy.sh -n dnode1 -i 1
system sh/cfg.sh -n dnode1 -c walLevel -v 1
system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 6
system sh/cfg.sh -n dnode1 -c cache -v 1
system sh/cfg.sh -n dnode1 -c minRows -v 10
system sh/exec.sh -n dnode1 -s start
sleep 100
sql connect
sql drop database if exists db
sql create database if not exists db
sql use db
sql create table stb1 (ts timestamp, c1 bool, c2 tinyint, c3 smallint, c4 int, c5 bigint, c6 float, c7 double, c8 binary(10), c9 nchar(10), c10 tinyint unsigned, c11 smallint unsigned, c12 int unsigned, c13 bigint unsigned) TAGS(t1 int, t2 binary(10), t3 double)
sql create table tb1 using stb1 tags(1,'1',1.0)
sql create table tb2 using stb1 tags(2,'2',2.0)
sql insert into tb1 values ('2021-11-11 09:00:00',true,1,1,1,1,1,1,"1","1",1,1,1,1);
sql insert into tb1 values ('2021-11-11 09:00:01',true,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
sql insert into tb1 values ('2021-11-11 09:00:02',true,2,NULL,2,NULL,2,NULL,"2",NULL,2,NULL,2,NULL);
sql insert into tb1 values ('2021-11-11 09:00:03',false,NULL,3,NULL,3,NULL,3,NULL,"3",NULL,3,NULL,3);
sql insert into tb1 values ('2021-11-11 09:00:04',true,4,4,4,4,4,4,"4","4",4,4,4,4);
sql insert into tb1 values ('2021-11-11 09:00:05',true,127,32767,2147483647,9223372036854775807,3.402823466e+38,1.79769e+308,"5","5",254,65534,4294967294,9223372036854775807);
sql insert into tb1 values ('2021-11-11 09:00:06',true,-127,-32767,-2147483647,-9223372036854775807,-3.402823466e+38,-1.79769e+308,"6","6",0,0,0,0);
sql_error select cast(* as tinyint) from tb1;
sql_error select cast(* as smallint) from tb1;
sql_error select cast(* as int) from tb1;
sql_error select cast(* as bool) from tb1;
sql_error select cast(* as bigint) as a from tb1;
sql_error select cast(* as bigint) + 1 as a from tb1;
sql_error select cast(tb1.* as bigint) + 1 as a from tb1;
sql_error select cast(* as bigint) from tb1;
sql_error select cast(c1 + c2 as bigint) from tb1;
sql_error select cast(c1 as binary(0)) from tb1;
sql_error select cast(c1 as binary(-1)) from tb1;
sql_error select cast(c1 as nchar(0)) from tb1;
sql_error select cast(c1 as nchar(-1)) from tb1;
sql_error select cast(c1 as tinyint) from tb1;
sql_error select cast(c1 as bool) from tb1;
sql_error select cast(c1 as smallint) from tb1;
sql_error select cast(c1 as int) from tb1;
sql_error select cast(c1 as float) from tb1;
sql_error select cast(c1 as double) from tb1;
sql_error select cast(c1 as tinyint unsigned) from tb1;
sql_error select cast(c1 as smallint unsigned) from tb1;
sql_error select cast(c1 as int unsigned) from tb1;
sql_error select cast(c2 as binary(0)) from tb1;
sql_error select cast(c2 as binary(-1)) from tb1;
sql_error select cast(c2 as nchar(0)) from tb1;
sql_error select cast(c2 as nchar(-1)) from tb1;
sql_error select cast(c2 as tinyint) from tb1;
sql_error select cast(c2 as bool) from tb1;
sql_error select cast(c2 as smallint) from tb1;
sql_error select cast(c2 as int) from tb1;
sql_error select cast(c2 as float) from tb1;
sql_error select cast(c2 as double) from tb1;
sql_error select cast(c2 as tinyint unsigned) from tb1;
sql_error select cast(c2 as smallint unsigned) from tb1;
sql_error select cast(c2 as int unsigned) from tb1;
sql select cast(c1 as bigint) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 0 then
return -1
endi
if $data40 != 1 then
return -1
endi
if $data50 != 1 then
return -1
endi
if $data60 != 1 then
return -1
endi
sql select cast(c1 as binary(10)) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != true then
return -1
endi
if $data10 != true then
return -1
endi
if $data20 != true then
return -1
endi
if $data30 != false then
return -1
endi
if $data40 != true then
return -1
endi
if $data50 != true then
return -1
endi
if $data60 != true then
return -1
endi
sql select cast(c1 as binary(1)) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != t then
return -1
endi
if $data10 != t then
return -1
endi
if $data20 != t then
return -1
endi
if $data30 != f then
return -1
endi
if $data40 != t then
return -1
endi
if $data50 != t then
return -1
endi
if $data60 != t then
return -1
endi
sql select cast(c1 as timestamp) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != @70-01-01 08:00:00.001@ then
return -1
endi
if $data10 != @70-01-01 08:00:00.001@ then
return -1
endi
if $data20 != @70-01-01 08:00:00.001@ then
return -1
endi
if $data30 != @70-01-01 08:00:00.000@ then
return -1
endi
if $data40 != @70-01-01 08:00:00.001@ then
return -1
endi
if $data50 != @70-01-01 08:00:00.001@ then
return -1
endi
if $data60 != @70-01-01 08:00:00.001@ then
return -1
endi
sql select cast(c1 as nchar(10)) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != true then
return -1
endi
if $data10 != true then
return -1
endi
if $data20 != true then
return -1
endi
if $data30 != false then
return -1
endi
if $data40 != true then
return -1
endi
if $data50 != true then
return -1
endi
if $data60 != true then
return -1
endi
sql select cast(c1 as nchar(1)) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != t then
return -1
endi
if $data10 != t then
return -1
endi
if $data20 != t then
return -1
endi
if $data30 != f then
return -1
endi
if $data40 != t then
return -1
endi
if $data50 != t then
return -1
endi
if $data60 != t then
return -1
endi
sql select cast(c1 as bigint unsigned) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 0 then
return -1
endi
if $data40 != 1 then
return -1
endi
if $data50 != 1 then
return -1
endi
if $data60 != 1 then
return -1
endi
sql select cast(c2 as bigint) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != 2 then
return -1
endi
if $data30 != NULL then
return -1
endi
if $data40 != 4 then
return -1
endi
if $data50 != 127 then
return -1
endi
if $data60 != -127 then
return -1
endi
sql select cast(c2 as binary(10)) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != 2 then
return -1
endi
if $data30 != NULL then
return -1
endi
if $data40 != 4 then
return -1
endi
if $data50 != 127 then
return -1
endi
if $data60 != -127 then
return -1
endi
sql select cast(c2 as binary(1)) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != 2 then
return -1
endi
if $data30 != NULL then
return -1
endi
if $data40 != 4 then
return -1
endi
if $data50 != 1 then
return -1
endi
if $data60 != - then
return -1
endi
sql select cast(c2 as timestamp) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != @70-01-01 08:00:00.001@ then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != @70-01-01 08:00:00.002@ then
return -1
endi
if $data30 != NULL then
return -1
endi
if $data40 != @70-01-01 08:00:00.004@ then
return -1
endi
if $data50 != @70-01-01 08:00:00.127@ then
return -1
endi
if $data60 != @70-01-01 08:00:00.-127@ then
print $data60
return -1
endi
sql select cast(c2 as nchar(10)) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != 2 then
return -1
endi
if $data30 != NULL then
return -1
endi
if $data40 != 4 then
return -1
endi
if $data50 != 127 then
return -1
endi
if $data60 != -127 then
return -1
endi
sql select cast(c2 as nchar(1)) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != 2 then
return -1
endi
if $data30 != NULL then
return -1
endi
if $data40 != 4 then
return -1
endi
if $data50 != 1 then
return -1
endi
if $data60 != - then
return -1
endi
sql select cast(c2 as bigint unsigned) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 0 then
return -1
endi
if $data40 != 1 then
return -1
endi
if $data50 != 1 then
return -1
endi
if $data60 != 1 then
return -1
endi
sql select cast(c2 + c3 as bigint) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != NULL then
return -1
endi
if $data40 != 8 then
return -1
endi
if $data50 != 32894 then
return -1
endi
if $data60 != -32894 then
return -1
endi
sql select cast((c2 + c3) as bigint) from tb1;
if $rows != 7 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != NULL then
return -1
endi
if $data40 != 8 then
return -1
endi
if $data50 != 32894 then
return -1
endi
if $data60 != -32894 then
return -1
endi
sql select cast(c1 as bigint)+c2 from tb1;
#system sh/exec.sh -n dnode1 -s stop -x SIGINT
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录