Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
4a07d2e7
T
TDengine
项目概览
taosdata
/
TDengine
大约 1 年 前同步成功
通知
1185
Star
22015
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
4a07d2e7
编写于
2月 10, 2022
作者:
S
Shengliang Guan
提交者:
GitHub
2月 10, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #10179 from taosdata/feature/3.0_wxy
TD-13338 SELECT statement translate code
上级
099f6f9e
090250f9
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
192 addition
and
27 deletion
+192
-27
include/nodes/nodes.h
include/nodes/nodes.h
+9
-1
include/util/taoserror.h
include/util/taoserror.h
+7
-4
source/libs/function/src/functionMgt.c
source/libs/function/src/functionMgt.c
+8
-0
source/libs/parser/src/astCreateFuncs.c
source/libs/parser/src/astCreateFuncs.c
+10
-2
source/libs/parser/src/parserImpl.c
source/libs/parser/src/parserImpl.c
+99
-13
source/libs/parser/test/newParserTest.cpp
source/libs/parser/test/newParserTest.cpp
+59
-7
未找到文件。
include/nodes/nodes.h
浏览文件 @
4a07d2e7
...
...
@@ -121,6 +121,14 @@ typedef struct SColumnNode {
typedef
struct
SValueNode
{
SExprNode
node
;
// QUERY_NODE_VALUE
char
*
literal
;
bool
isDuration
;
union
{
bool
b
;
int64_t
i
;
uint64_t
u
;
double
d
;
char
*
p
;
}
datum
;
}
SValueNode
;
typedef
enum
EOperatorType
{
...
...
@@ -181,7 +189,7 @@ typedef struct SNodeListNode {
}
SNodeListNode
;
typedef
struct
SFunctionNode
{
SExprNode
typ
e
;
// QUERY_NODE_FUNCTION
SExprNode
nod
e
;
// QUERY_NODE_FUNCTION
char
functionName
[
TSDB_FUNC_NAME_LEN
];
int32_t
funcId
;
SNodeList
*
pParameterList
;
...
...
include/util/taoserror.h
浏览文件 @
4a07d2e7
...
...
@@ -444,10 +444,13 @@ int32_t* taosGetErrno();
#define TSDB_CODE_SCH_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2502) //scheduler internal error
//parser
#define TSDB_CODE_PARSER_INVALID_COLUMN TAOS_DEF_ERROR_CODE(0, 0x2601) //invalid column name
#define TSDB_CODE_PARSER_TABLE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x2602) //table not exist
#define TSDB_CODE_PARSER_AMBIGUOUS_COLUMN TAOS_DEF_ERROR_CODE(0, 0x2603) //ambiguous column
#define TSDB_CODE_PARSER_WRONG_VALUE_TYPE TAOS_DEF_ERROR_CODE(0, 0x2604) //wrong value type
#define TSDB_CODE_PAR_INVALID_COLUMN TAOS_DEF_ERROR_CODE(0, 0x2601) //invalid column name
#define TSDB_CODE_PAR_TABLE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x2602) //table not exist
#define TSDB_CODE_PAR_AMBIGUOUS_COLUMN TAOS_DEF_ERROR_CODE(0, 0x2603) //ambiguous column
#define TSDB_CODE_PAR_WRONG_VALUE_TYPE TAOS_DEF_ERROR_CODE(0, 0x2604) //wrong value type
#define TSDB_CODE_PAR_FUNTION_PARA_NUM TAOS_DEF_ERROR_CODE(0, 0x2605) //invalid number of arguments
#define TSDB_CODE_PAR_FUNTION_PARA_TYPE TAOS_DEF_ERROR_CODE(0, 0x2606) //inconsistent datatypes
#define TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION TAOS_DEF_ERROR_CODE(0, 0x2607) //there mustn't be aggregation
#ifdef __cplusplus
}
...
...
source/libs/function/src/functionMgt.c
浏览文件 @
4a07d2e7
...
...
@@ -78,3 +78,11 @@ FuncDef setExecFuncs(FuncDef def, FExecGetEnv getEnv, FExecInit init, FExecProce
int32_t
registerFunc
(
FuncDef
func
)
{
}
int32_t
fmGetFuncResultType
(
FuncMgtHandle
handle
,
SFunctionNode
*
pFunc
)
{
return
TSDB_CODE_SUCCESS
;
}
bool
fmIsAggFunc
(
int32_t
funcId
)
{
return
false
;
}
source/libs/parser/src/astCreateFuncs.c
浏览文件 @
4a07d2e7
...
...
@@ -118,14 +118,22 @@ SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken*
val
->
literal
=
strndup
(
pLiteral
->
z
,
pLiteral
->
n
);
CHECK_OUT_OF_MEM
(
val
->
literal
);
val
->
node
.
resType
.
type
=
dataType
;
val
->
node
.
resType
.
bytes
=
tDataTypes
[
TSDB_DATA_TYPE_BOOL
].
bytes
;
val
->
node
.
resType
.
bytes
=
tDataTypes
[
dataType
].
bytes
;
if
(
TSDB_DATA_TYPE_TIMESTAMP
==
dataType
)
{
val
->
node
.
resType
.
precision
=
TSDB_TIME_PRECISION_MILLI
;
}
return
(
SNode
*
)
val
;
}
SNode
*
createDurationValueNode
(
SAstCreateContext
*
pCxt
,
const
SToken
*
pLiteral
)
{
SValueNode
*
val
=
(
SValueNode
*
)
nodesMakeNode
(
QUERY_NODE_VALUE
);
CHECK_OUT_OF_MEM
(
val
);
// todo : calc, for example, 10s
val
->
literal
=
strndup
(
pLiteral
->
z
,
pLiteral
->
n
);
CHECK_OUT_OF_MEM
(
val
->
literal
);
val
->
isDuration
=
true
;
val
->
node
.
resType
.
type
=
TSDB_DATA_TYPE_BIGINT
;
val
->
node
.
resType
.
bytes
=
tDataTypes
[
TSDB_DATA_TYPE_BIGINT
].
bytes
;
val
->
node
.
resType
.
precision
=
TSDB_TIME_PRECISION_MILLI
;
return
(
SNode
*
)
val
;
}
...
...
source/libs/parser/src/parserImpl.c
浏览文件 @
4a07d2e7
...
...
@@ -16,7 +16,10 @@
#include "parserImpl.h"
#include "astCreateContext.h"
#include "functionMgt.h"
#include "parserInt.h"
#include "tglobal.h"
#include "ttime.h"
#include "ttoken.h"
typedef
void
*
(
*
FMalloc
)(
size_t
);
...
...
@@ -240,6 +243,7 @@ typedef enum ESqlClause {
typedef
struct
STranslateContext
{
SParseContext
*
pParseCxt
;
FuncMgtHandle
fmgt
;
int32_t
errCode
;
SMsgBuf
msgBuf
;
SArray
*
pNsLevel
;
// element is SArray*, the element of this subarray is STableNode*
...
...
@@ -251,21 +255,30 @@ static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode);
static
char
*
getSyntaxErrFormat
(
int32_t
errCode
)
{
switch
(
errCode
)
{
case
TSDB_CODE_PAR
SER
_INVALID_COLUMN
:
case
TSDB_CODE_PAR_INVALID_COLUMN
:
return
"Invalid column name : %s"
;
case
TSDB_CODE_PAR
SER
_TABLE_NOT_EXIST
:
case
TSDB_CODE_PAR_TABLE_NOT_EXIST
:
return
"Table does not exist : %s"
;
case
TSDB_CODE_PAR
SER
_AMBIGUOUS_COLUMN
:
case
TSDB_CODE_PAR_AMBIGUOUS_COLUMN
:
return
"Column ambiguously defined : %s"
;
case
TSDB_CODE_PAR
SER
_WRONG_VALUE_TYPE
:
case
TSDB_CODE_PAR_WRONG_VALUE_TYPE
:
return
"Invalid value type : %s"
;
case
TSDB_CODE_PAR_FUNTION_PARA_NUM
:
return
"Invalid number of arguments : %s"
;
case
TSDB_CODE_PAR_FUNTION_PARA_TYPE
:
return
"Inconsistent datatypes : %s"
;
case
TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
:
return
"There mustn't be aggregation"
;
default:
return
"Unknown error"
;
}
}
static
int32_t
generateSyntaxErrMsg
(
STranslateContext
*
pCxt
,
int32_t
errCode
,
const
char
*
additionalInfo
)
{
snprintf
(
pCxt
->
msgBuf
.
buf
,
pCxt
->
msgBuf
.
len
,
getSyntaxErrFormat
(
errCode
),
additionalInfo
);
static
int32_t
generateSyntaxErrMsg
(
STranslateContext
*
pCxt
,
int32_t
errCode
,
...)
{
va_list
vArgList
;
va_start
(
vArgList
,
errCode
);
vsnprintf
(
pCxt
->
msgBuf
.
buf
,
pCxt
->
msgBuf
.
len
,
getSyntaxErrFormat
(
errCode
),
vArgList
);
va_end
(
vArgList
);
pCxt
->
errCode
=
errCode
;
return
errCode
;
}
...
...
@@ -394,7 +407,7 @@ static bool translateColumnWithPrefix(STranslateContext* pCxt, SColumnNode* pCol
if
(
findAndSetColumn
(
pCol
,
pTable
))
{
break
;
}
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR
SER
_INVALID_COLUMN
,
pCol
->
colName
);
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_INVALID_COLUMN
,
pCol
->
colName
);
return
false
;
}
}
...
...
@@ -409,14 +422,14 @@ static bool translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNode* p
STableNode
*
pTable
=
taosArrayGetP
(
pTables
,
i
);
if
(
findAndSetColumn
(
pCol
,
pTable
))
{
if
(
found
)
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR
SER
_AMBIGUOUS_COLUMN
,
pCol
->
colName
);
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_AMBIGUOUS_COLUMN
,
pCol
->
colName
);
return
false
;
}
found
=
true
;
}
}
if
(
!
found
)
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR
SER
_INVALID_COLUMN
,
pCol
->
colName
);
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_INVALID_COLUMN
,
pCol
->
colName
);
return
false
;
}
return
true
;
...
...
@@ -429,8 +442,72 @@ static bool translateColumn(STranslateContext* pCxt, SColumnNode* pCol) {
return
translateColumnWithoutPrefix
(
pCxt
,
pCol
);
}
// check literal format
static
int32_t
trimStringCopy
(
const
char
*
src
,
int32_t
len
,
char
*
dst
)
{
// delete escape character: \\, \', \"
char
delim
=
src
[
0
];
int32_t
cnt
=
0
;
int32_t
j
=
0
;
for
(
uint32_t
k
=
1
;
k
<
len
-
1
;
++
k
)
{
if
(
src
[
k
]
==
'\\'
||
(
src
[
k
]
==
delim
&&
src
[
k
+
1
]
==
delim
))
{
dst
[
j
]
=
src
[
k
+
1
];
cnt
++
;
j
++
;
k
++
;
continue
;
}
dst
[
j
]
=
src
[
k
];
j
++
;
}
dst
[
j
]
=
'\0'
;
return
j
;
}
static
bool
translateValue
(
STranslateContext
*
pCxt
,
SValueNode
*
pVal
)
{
if
(
pVal
->
isDuration
)
{
char
unit
=
0
;
if
(
parseAbsoluteDuration
(
pVal
->
literal
,
strlen
(
pVal
->
literal
),
&
pVal
->
datum
.
i
,
&
unit
,
pVal
->
node
.
resType
.
precision
)
!=
TSDB_CODE_SUCCESS
)
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
,
pVal
->
literal
);
return
false
;
}
}
else
{
switch
(
pVal
->
node
.
resType
.
type
)
{
case
TSDB_DATA_TYPE_NULL
:
break
;
case
TSDB_DATA_TYPE_BOOL
:
pVal
->
datum
.
b
=
(
0
==
strcasecmp
(
pVal
->
literal
,
"true"
));
break
;
case
TSDB_DATA_TYPE_BIGINT
:
{
char
*
endPtr
=
NULL
;
pVal
->
datum
.
i
=
strtoull
(
pVal
->
literal
,
&
endPtr
,
10
);
break
;
}
case
TSDB_DATA_TYPE_DOUBLE
:
{
char
*
endPtr
=
NULL
;
pVal
->
datum
.
d
=
strtold
(
pVal
->
literal
,
&
endPtr
);
break
;
}
case
TSDB_DATA_TYPE_BINARY
:
{
int32_t
n
=
strlen
(
pVal
->
literal
);
pVal
->
datum
.
p
=
calloc
(
1
,
n
);
trimStringCopy
(
pVal
->
literal
,
n
,
pVal
->
datum
.
p
);
break
;
}
case
TSDB_DATA_TYPE_TIMESTAMP
:
{
int32_t
n
=
strlen
(
pVal
->
literal
);
char
*
tmp
=
calloc
(
1
,
n
);
int32_t
len
=
trimStringCopy
(
pVal
->
literal
,
n
,
tmp
);
if
(
taosParseTime
(
tmp
,
&
pVal
->
datum
.
u
,
len
,
pVal
->
node
.
resType
.
precision
,
tsDaylight
)
!=
TSDB_CODE_SUCCESS
)
{
tfree
(
tmp
);
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
,
pVal
->
literal
);
return
false
;
}
tfree
(
tmp
);
break
;
}
default:
break
;
}
}
return
true
;
}
...
...
@@ -440,7 +517,7 @@ static bool translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
if
(
nodesIsArithmeticOp
(
pOp
))
{
if
(
TSDB_DATA_TYPE_JSON
==
ldt
.
type
||
TSDB_DATA_TYPE_BLOB
==
ldt
.
type
||
TSDB_DATA_TYPE_JSON
==
rdt
.
type
||
TSDB_DATA_TYPE_BLOB
==
rdt
.
type
)
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR
SER
_WRONG_VALUE_TYPE
,
((
SExprNode
*
)(
pOp
->
pRight
))
->
aliasName
);
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
,
((
SExprNode
*
)(
pOp
->
pRight
))
->
aliasName
);
return
false
;
}
pOp
->
node
.
resType
.
type
=
TSDB_DATA_TYPE_DOUBLE
;
...
...
@@ -449,7 +526,7 @@ static bool translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
}
else
if
(
nodesIsComparisonOp
(
pOp
))
{
if
(
TSDB_DATA_TYPE_JSON
==
ldt
.
type
||
TSDB_DATA_TYPE_BLOB
==
ldt
.
type
||
TSDB_DATA_TYPE_JSON
==
rdt
.
type
||
TSDB_DATA_TYPE_BLOB
==
rdt
.
type
)
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR
SER
_WRONG_VALUE_TYPE
,
((
SExprNode
*
)(
pOp
->
pRight
))
->
aliasName
);
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
,
((
SExprNode
*
)(
pOp
->
pRight
))
->
aliasName
);
return
false
;
}
pOp
->
node
.
resType
.
type
=
TSDB_DATA_TYPE_BOOL
;
...
...
@@ -463,6 +540,15 @@ static bool translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
}
static
bool
translateFunction
(
STranslateContext
*
pCxt
,
SFunctionNode
*
pFunc
)
{
int32_t
code
=
fmGetFuncResultType
(
pCxt
->
fmgt
,
pFunc
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
generateSyntaxErrMsg
(
pCxt
,
code
,
pFunc
->
functionName
);
return
false
;
}
if
(
fmIsAggFunc
(
pFunc
->
funcId
)
&&
(
SQL_CLAUSE_FROM
==
pCxt
->
currClause
||
SQL_CLAUSE_WHERE
==
pCxt
->
currClause
))
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
);
return
false
;
}
return
true
;
}
...
...
@@ -504,7 +590,7 @@ static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) {
code
=
catalogGetTableMeta
(
pCxt
->
pParseCxt
->
pCatalog
,
pCxt
->
pParseCxt
->
pTransporter
,
&
(
pCxt
->
pParseCxt
->
mgmtEpSet
),
toName
(
pCxt
->
pParseCxt
->
acctId
,
pRealTable
,
&
name
),
&
(
pRealTable
->
pMeta
));
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR
SER
_TABLE_NOT_EXIST
,
pRealTable
->
table
.
tableName
);
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_TABLE_NOT_EXIST
,
pRealTable
->
table
.
tableName
);
}
code
=
addNamespace
(
pCxt
,
pRealTable
);
break
;
...
...
source/libs/parser/test/newParserTest.cpp
浏览文件 @
4a07d2e7
...
...
@@ -118,6 +118,53 @@ private:
return
"Unknown Data Type "
+
to_string
(
dt
.
type
);
}
void
valueNodeToStr
(
const
SValueNode
*
pVal
,
string
&
str
,
bool
isProject
)
{
switch
(
pVal
->
node
.
resType
.
type
)
{
case
TSDB_DATA_TYPE_NULL
:
str
.
append
(
"null"
);
break
;
case
TSDB_DATA_TYPE_BOOL
:
str
.
append
(
pVal
->
datum
.
b
?
"true"
:
"false"
);
break
;
case
TSDB_DATA_TYPE_TINYINT
:
case
TSDB_DATA_TYPE_SMALLINT
:
case
TSDB_DATA_TYPE_INT
:
case
TSDB_DATA_TYPE_BIGINT
:
str
.
append
(
to_string
(
pVal
->
datum
.
i
));
break
;
case
TSDB_DATA_TYPE_FLOAT
:
case
TSDB_DATA_TYPE_DOUBLE
:
str
.
append
(
to_string
(
pVal
->
datum
.
d
));
break
;
case
TSDB_DATA_TYPE_BINARY
:
case
TSDB_DATA_TYPE_NCHAR
:
case
TSDB_DATA_TYPE_VARCHAR
:
case
TSDB_DATA_TYPE_VARBINARY
:
str
.
append
(
pVal
->
datum
.
p
);
break
;
case
TSDB_DATA_TYPE_TIMESTAMP
:
str
.
append
(
to_string
(
pVal
->
datum
.
u
));
break
;
case
TSDB_DATA_TYPE_UTINYINT
:
case
TSDB_DATA_TYPE_USMALLINT
:
case
TSDB_DATA_TYPE_UINT
:
case
TSDB_DATA_TYPE_UBIGINT
:
str
.
append
(
to_string
(
pVal
->
datum
.
u
));
break
;
case
TSDB_DATA_TYPE_JSON
:
case
TSDB_DATA_TYPE_DECIMAL
:
case
TSDB_DATA_TYPE_BLOB
:
str
.
append
(
"JSON or DECIMAL or BLOB"
);
break
;
default:
break
;
}
str
.
append
(
" ["
+
dataTypeToStr
(
pVal
->
node
.
resType
)
+
"]"
);
if
(
isProject
)
{
str
.
append
(
" AS "
+
string
(
pVal
->
node
.
aliasName
));
}
}
void
nodeToStr
(
const
SNode
*
node
,
string
&
str
,
bool
isProject
)
{
if
(
nullptr
==
node
)
{
return
;
...
...
@@ -142,12 +189,7 @@ private:
break
;
}
case
QUERY_NODE_VALUE
:
{
SValueNode
*
pVal
=
(
SValueNode
*
)
node
;
str
.
append
(
pVal
->
literal
);
str
.
append
(
" ["
+
dataTypeToStr
(
pVal
->
node
.
resType
)
+
"]"
);
if
(
isProject
)
{
str
.
append
(
" AS "
+
string
(
pVal
->
node
.
aliasName
));
}
valueNodeToStr
((
SValueNode
*
)
node
,
str
,
isProject
);
break
;
}
case
QUERY_NODE_OPERATOR
:
{
...
...
@@ -391,10 +433,20 @@ TEST_F(NewParserTest, selectSimple) {
ASSERT_TRUE
(
run
());
}
TEST_F
(
NewParserTest
,
selectConstant
)
{
setDatabase
(
"root"
,
"test"
);
bind
(
"SELECT 123, 20.4, 'abc',
\"
wxy
\"
, TIMESTAMP '2022-02-09 17:30:20', true, false, 10s FROM t1"
);
ASSERT_TRUE
(
run
());
bind
(
"SELECT 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc',
\"
wxy
\"
, TIMESTAMP '2022-02-09 17:30:20', true, false, 15s FROM t1"
);
ASSERT_TRUE
(
run
());
}
TEST_F
(
NewParserTest
,
selectExpression
)
{
setDatabase
(
"root"
,
"test"
);
bind
(
"SELECT
c1 + 10, c2
FROM t1"
);
bind
(
"SELECT
ts + 10s, c1 + 10, concat(c2, 'abc')
FROM t1"
);
ASSERT_TRUE
(
run
());
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录