Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
a5e9d8f5
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看板
提交
a5e9d8f5
编写于
2月 09, 2022
作者:
X
Xiaoyu Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
TD-13338 SELECT statement translate code
上级
655b7ec5
变更
11
展开全部
隐藏空白更改
内联
并排
Showing
11 changed file
with
944 addition
and
696 deletion
+944
-696
include/nodes/nodes.h
include/nodes/nodes.h
+10
-13
include/util/taoserror.h
include/util/taoserror.h
+1
-0
source/libs/parser/inc/astCreateFuncs.h
source/libs/parser/inc/astCreateFuncs.h
+1
-0
source/libs/parser/inc/new_sql.y
source/libs/parser/inc/new_sql.y
+7
-1
source/libs/parser/src/astCreateFuncs.c
source/libs/parser/src/astCreateFuncs.c
+12
-0
source/libs/parser/src/new_sql.c
source/libs/parser/src/new_sql.c
+593
-566
source/libs/parser/src/parserImpl.c
source/libs/parser/src/parserImpl.c
+109
-56
source/libs/parser/src/ttokenizer.c
source/libs/parser/src/ttokenizer.c
+3
-1
source/libs/parser/test/newParserTest.cpp
source/libs/parser/test/newParserTest.cpp
+166
-37
source/nodes/src/nodesTraverseFuncs.c
source/nodes/src/nodesTraverseFuncs.c
+21
-21
source/nodes/src/nodesUtilFuncs.c
source/nodes/src/nodesUtilFuncs.c
+21
-1
未找到文件。
include/nodes/nodes.h
浏览文件 @
a5e9d8f5
...
...
@@ -31,16 +31,7 @@ extern "C" {
for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext)
// only be use in FOREACH
#define ERASE_NODE(list) \
if (NULL == cell->pPrev) { \
(list)->pHead = cell->pNext; \
} else { \
cell->pPrev->pNext = cell->pNext; \
cell->pNext->pPrev = cell->pPrev; \
} \
SListCell* tmp = cell; \
cell = cell->pNext; \
tfree(tmp);
#define ERASE_NODE(list) cell = nodesListErase(list, cell);
#define REPLACE_NODE(newNode) cell->pNode = (SNode*)(newNode)
...
...
@@ -343,18 +334,22 @@ void nodesDestroyNode(SNode* pNode);
SNodeList
*
nodesMakeList
();
SNodeList
*
nodesListAppend
(
SNodeList
*
pList
,
SNode
*
pNode
);
SListCell
*
nodesListErase
(
SNodeList
*
pList
,
SListCell
*
pCell
);
SNode
*
nodesListGetNode
(
SNodeList
*
pList
,
int32_t
index
);
void
nodesDestroyList
(
SNodeList
*
pList
);
typedef
bool
(
*
FQueryNodeWalker
)(
SNode
*
pNode
,
void
*
pContext
);
typedef
enum
EDealRes
{
DEAL_RES_CONTINUE
=
1
,
DEAL_RES_IGNORE_CHILD
,
DEAL_RES_ERROR
,
}
EDealRes
;
typedef
EDealRes
(
*
FQueryNodeWalker
)(
SNode
*
pNode
,
void
*
pContext
);
void
nodesWalkNode
(
SNode
*
pNode
,
FQueryNodeWalker
walker
,
void
*
pContext
);
void
nodesWalkList
(
SNodeList
*
pList
,
FQueryNodeWalker
walker
,
void
*
pContext
);
void
nodesWalkNodePostOrder
(
SNode
*
pNode
,
FQueryNodeWalker
walker
,
void
*
pContext
);
void
nodesWalkListPostOrder
(
SNodeList
*
pList
,
FQueryNodeWalker
walker
,
void
*
pContext
);
bool
nodesWalkStmt
(
SNode
*
pNode
,
FQueryNodeWalker
walker
,
void
*
pContext
);
bool
nodesEqualNode
(
const
SNode
*
a
,
const
SNode
*
b
);
void
nodesCloneNode
(
const
SNode
*
pNode
);
...
...
@@ -362,6 +357,8 @@ void nodesCloneNode(const SNode* pNode);
int32_t
nodesNodeToString
(
const
SNode
*
pNode
,
char
**
pStr
,
int32_t
*
pLen
);
int32_t
nodesStringToNode
(
const
char
*
pStr
,
SNode
**
pNode
);
bool
nodesIsExprNode
(
const
SNode
*
pNode
);
bool
nodesIsArithmeticOp
(
const
SOperatorNode
*
pOp
);
bool
nodesIsComparisonOp
(
const
SOperatorNode
*
pOp
);
bool
nodesIsJsonOp
(
const
SOperatorNode
*
pOp
);
...
...
include/util/taoserror.h
浏览文件 @
a5e9d8f5
...
...
@@ -453,6 +453,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_PAR_FUNTION_PARA_TYPE TAOS_DEF_ERROR_CODE(0, 0x2607) //Inconsistent datatypes
#define TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION TAOS_DEF_ERROR_CODE(0, 0x2608) //There mustn't be aggregation
#define TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT TAOS_DEF_ERROR_CODE(0, 0x2609) //ORDER BY item must be the number of a SELECT-list expression
#define TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION TAOS_DEF_ERROR_CODE(0, 0x260A) //Not a GROUP BY expression
#ifdef __cplusplus
}
...
...
source/libs/parser/inc/astCreateFuncs.h
浏览文件 @
a5e9d8f5
...
...
@@ -55,6 +55,7 @@ SNode* createSessionWindowNode(SAstCreateContext* pCxt, SNode* pCol, const SToke
SNode
*
createStateWindowNode
(
SAstCreateContext
*
pCxt
,
SNode
*
pCol
);
SNode
*
createIntervalWindowNode
(
SAstCreateContext
*
pCxt
,
SNode
*
pInterval
,
SNode
*
pOffset
,
SNode
*
pSliding
,
SNode
*
pFill
);
SNode
*
createFillNode
(
SAstCreateContext
*
pCxt
,
EFillMode
mode
,
SNode
*
pValues
);
SNode
*
createGroupingSetNode
(
SAstCreateContext
*
pCxt
,
SNode
*
pNode
);
SNode
*
addWhereClause
(
SAstCreateContext
*
pCxt
,
SNode
*
pStmt
,
SNode
*
pWhere
);
SNode
*
addPartitionByClause
(
SAstCreateContext
*
pCxt
,
SNode
*
pStmt
,
SNodeList
*
pPartitionByList
);
...
...
source/libs/parser/inc/new_sql.y
浏览文件 @
a5e9d8f5
...
...
@@ -238,6 +238,7 @@ joined_table(A) ::=
%type join_type { EJoinType }
%destructor join_type { PARSER_DESTRUCTOR_TRACE; }
join_type(A) ::= . { PARSER_TRACE; A = JOIN_TYPE_INNER; }
join_type(A) ::= INNER. { PARSER_TRACE; A = JOIN_TYPE_INNER; }
/************************************************ query_specification *************************************************/
...
...
@@ -315,7 +316,12 @@ fill_mode(A) ::= NEXT.
%type group_by_clause_opt { SNodeList* }
%destructor group_by_clause_opt { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
group_by_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
group_by_clause_opt(A) ::= GROUP BY expression_list(B). { PARSER_TRACE; A = B; }
group_by_clause_opt(A) ::= GROUP BY group_by_list(B). { PARSER_TRACE; A = B; }
%type group_by_list { SNodeList* }
%destructor group_by_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
group_by_list(A) ::= expression(B). { PARSER_TRACE; A = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, B))); }
group_by_list(A) ::= group_by_list(B) NK_COMMA expression(C). { PARSER_TRACE; A = addNodeToList(pCxt, B, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, C))); }
having_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
having_clause_opt(A) ::= HAVING search_condition(B). { PARSER_TRACE; A = B; }
...
...
source/libs/parser/src/astCreateFuncs.c
浏览文件 @
a5e9d8f5
...
...
@@ -242,6 +242,9 @@ SNode* createOrderByExprNode(SAstCreateContext* pCxt, SNode* pExpr, EOrder order
CHECK_OUT_OF_MEM
(
orderByExpr
);
orderByExpr
->
pExpr
=
pExpr
;
orderByExpr
->
order
=
order
;
if
(
NULL_ORDER_DEFAULT
==
nullOrder
)
{
nullOrder
=
(
ORDER_ASC
==
order
?
NULL_ORDER_FIRST
:
NULL_ORDER_LAST
);
}
orderByExpr
->
nullOrder
=
nullOrder
;
return
(
SNode
*
)
orderByExpr
;
}
...
...
@@ -279,6 +282,15 @@ SNode* createFillNode(SAstCreateContext* pCxt, EFillMode mode, SNode* pValues) {
return
(
SNode
*
)
fill
;
}
SNode
*
createGroupingSetNode
(
SAstCreateContext
*
pCxt
,
SNode
*
pNode
)
{
SGroupingSetNode
*
groupingSet
=
(
SGroupingSetNode
*
)
nodesMakeNode
(
QUERY_NODE_GROUPING_SET
);
CHECK_OUT_OF_MEM
(
groupingSet
);
groupingSet
->
groupingSetType
=
GP_TYPE_NORMAL
;
groupingSet
->
pParameterList
=
nodesMakeList
();
nodesListAppend
(
groupingSet
->
pParameterList
,
pNode
);
return
(
SNode
*
)
groupingSet
;
}
SNode
*
setProjectionAlias
(
SAstCreateContext
*
pCxt
,
SNode
*
pNode
,
const
SToken
*
pAlias
)
{
strncpy
(((
SExprNode
*
)
pNode
)
->
aliasName
,
pAlias
->
z
,
pAlias
->
n
);
return
pNode
;
...
...
source/libs/parser/src/new_sql.c
浏览文件 @
a5e9d8f5
此差异已折叠。
点击以展开。
source/libs/parser/src/parserImpl.c
浏览文件 @
a5e9d8f5
...
...
@@ -116,10 +116,6 @@ static uint32_t toNewTokenId(uint32_t tokenId) {
return
NEW_TK_FROM
;
case
TK_JOIN
:
return
NEW_TK_JOIN
;
// case TK_ON:
// return NEW_TK_ON;
// case TK_INNER:
// return NEW_TK_INNER;
// case TK_PARTITION:
// return NEW_TK_PARTITION;
case
TK_SESSION
:
...
...
@@ -163,6 +159,8 @@ static uint32_t toNewTokenId(uint32_t tokenId) {
case
TK_OFFSET
:
return
NEW_TK_OFFSET
;
case
TK_SPACE
:
case
NEW_TK_ON
:
case
NEW_TK_INNER
:
break
;
default:
printf
(
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!tokenId = %d
\n
"
,
tokenId
);
...
...
@@ -248,6 +246,10 @@ typedef enum ESqlClause {
}
ESqlClause
;
static
bool
afterGroupBy
(
ESqlClause
clause
)
{
return
clause
>
SQL_CLAUSE_GROUP_BY
;
}
static
bool
beforeHaving
(
ESqlClause
clause
)
{
return
clause
<
SQL_CLAUSE_HAVING
;
}
...
...
@@ -259,7 +261,7 @@ typedef struct STranslateContext {
SArray
*
pNsLevel
;
// element is SArray*, the element of this subarray is STableNode*
int32_t
currLevel
;
ESqlClause
currClause
;
void
*
pEx
t
;
SSelectStmt
*
pCurrStm
t
;
}
STranslateContext
;
static
int32_t
translateSubquery
(
STranslateContext
*
pCxt
,
SNode
*
pNode
);
...
...
@@ -284,6 +286,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return
"There mustn't be aggregation"
;
case
TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT
:
return
"ORDER BY item must be the number of a SELECT-list expression"
;
case
TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
:
return
"Not a GROUP BY expression"
;
default:
return
"Unknown error"
;
}
...
...
@@ -415,7 +419,7 @@ static bool findAndSetColumn(SColumnNode* pCol, const STableNode* pTable) {
return
found
;
}
static
bool
translateColumnWithPrefix
(
STranslateContext
*
pCxt
,
SColumnNode
*
pCol
)
{
static
EDealRes
translateColumnWithPrefix
(
STranslateContext
*
pCxt
,
SColumnNode
*
pCol
)
{
SArray
*
pTables
=
taosArrayGetP
(
pCxt
->
pNsLevel
,
pCxt
->
currLevel
);
size_t
nums
=
taosArrayGetSize
(
pTables
);
for
(
size_t
i
=
0
;
i
<
nums
;
++
i
)
{
...
...
@@ -425,13 +429,13 @@ static bool translateColumnWithPrefix(STranslateContext* pCxt, SColumnNode* pCol
break
;
}
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_INVALID_COLUMN
,
pCol
->
colName
);
return
false
;
return
DEAL_RES_ERROR
;
}
}
return
true
;
return
DEAL_RES_CONTINUE
;
}
static
bool
translateColumnWithoutPrefix
(
STranslateContext
*
pCxt
,
SColumnNode
*
pCol
)
{
static
EDealRes
translateColumnWithoutPrefix
(
STranslateContext
*
pCxt
,
SColumnNode
*
pCol
)
{
SArray
*
pTables
=
taosArrayGetP
(
pCxt
->
pNsLevel
,
pCxt
->
currLevel
);
size_t
nums
=
taosArrayGetSize
(
pTables
);
bool
found
=
false
;
...
...
@@ -440,20 +444,20 @@ static bool translateColumnWithoutPrefix(STranslateContext* pCxt, SColumnNode* p
if
(
findAndSetColumn
(
pCol
,
pTable
))
{
if
(
found
)
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_AMBIGUOUS_COLUMN
,
pCol
->
colName
);
return
false
;
return
DEAL_RES_ERROR
;
}
found
=
true
;
}
}
if
(
!
found
)
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_INVALID_COLUMN
,
pCol
->
colName
);
return
false
;
return
DEAL_RES_ERROR
;
}
return
true
;
return
DEAL_RES_CONTINUE
;
}
static
bool
translateColumnUseAlias
(
STranslateContext
*
pCxt
,
SColumnNode
*
pCol
)
{
SNodeList
*
pProjectionList
=
pCxt
->
p
Ex
t
;
SNodeList
*
pProjectionList
=
pCxt
->
p
CurrStmt
->
pProjectionLis
t
;
SNode
*
pNode
;
FOREACH
(
pNode
,
pProjectionList
)
{
SExprNode
*
pExpr
=
(
SExprNode
*
)
pNode
;
...
...
@@ -465,10 +469,10 @@ static bool translateColumnUseAlias(STranslateContext* pCxt, SColumnNode* pCol)
return
false
;
}
static
bool
translateColumn
(
STranslateContext
*
pCxt
,
SColumnNode
*
pCol
)
{
static
EDealRes
translateColumn
(
STranslateContext
*
pCxt
,
SColumnNode
*
pCol
)
{
// count(*)/first(*)/last(*)
if
(
0
==
strcmp
(
pCol
->
colName
,
"*"
))
{
return
true
;
return
DEAL_RES_CONTINUE
;
}
if
(
'\0'
!=
pCol
->
tableAlias
[
0
])
{
return
translateColumnWithPrefix
(
pCxt
,
pCol
);
...
...
@@ -477,7 +481,7 @@ static bool translateColumn(STranslateContext* pCxt, SColumnNode* pCol) {
if
(
SQL_CLAUSE_ORDER_BY
==
pCxt
->
currClause
)
{
found
=
translateColumnUseAlias
(
pCxt
,
pCol
);
}
return
found
?
true
:
translateColumnWithoutPrefix
(
pCxt
,
pCol
);
return
found
?
DEAL_RES_CONTINUE
:
translateColumnWithoutPrefix
(
pCxt
,
pCol
);
}
static
int32_t
trimStringCopy
(
const
char
*
src
,
int32_t
len
,
char
*
dst
)
{
...
...
@@ -500,12 +504,12 @@ static int32_t trimStringCopy(const char* src, int32_t len, char* dst) {
return
j
;
}
static
bool
translateValue
(
STranslateContext
*
pCxt
,
SValueNode
*
pVal
)
{
static
EDealRes
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
;
return
DEAL_RES_ERROR
;
}
}
else
{
switch
(
pVal
->
node
.
resType
.
type
)
{
...
...
@@ -552,7 +556,7 @@ static bool translateValue(STranslateContext* pCxt, SValueNode* pVal) {
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
;
return
DEAL_RES_ERROR
;
}
tfree
(
tmp
);
break
;
...
...
@@ -565,55 +569,56 @@ static bool translateValue(STranslateContext* pCxt, SValueNode* pVal) {
break
;
}
}
return
true
;
return
DEAL_RES_CONTINUE
;
}
static
bool
translateOperator
(
STranslateContext
*
pCxt
,
SOperatorNode
*
pOp
)
{
static
EDealRes
translateOperator
(
STranslateContext
*
pCxt
,
SOperatorNode
*
pOp
)
{
SDataType
ldt
=
((
SExprNode
*
)(
pOp
->
pLeft
))
->
resType
;
SDataType
rdt
=
((
SExprNode
*
)(
pOp
->
pRight
))
->
resType
;
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_WRONG_VALUE_TYPE
,
((
SExprNode
*
)(
pOp
->
pRight
))
->
aliasName
);
return
false
;
return
DEAL_RES_ERROR
;
}
pOp
->
node
.
resType
.
type
=
TSDB_DATA_TYPE_DOUBLE
;
pOp
->
node
.
resType
.
bytes
=
tDataTypes
[
TSDB_DATA_TYPE_DOUBLE
].
bytes
;
return
true
;
}
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_WRONG_VALUE_TYPE
,
((
SExprNode
*
)(
pOp
->
pRight
))
->
aliasName
);
return
false
;
return
DEAL_RES_ERROR
;
}
pOp
->
node
.
resType
.
type
=
TSDB_DATA_TYPE_BOOL
;
pOp
->
node
.
resType
.
bytes
=
tDataTypes
[
TSDB_DATA_TYPE_BOOL
].
bytes
;
return
true
;
}
else
{
// todo json operator
return
true
;
}
return
true
;
return
DEAL_RES_CONTINUE
;
}
static
bool
translateFunction
(
STranslateContext
*
pCxt
,
SFunctionNode
*
pFunc
)
{
static
EDealRes
translateFunction
(
STranslateContext
*
pCxt
,
SFunctionNode
*
pFunc
)
{
if
(
TSDB_CODE_SUCCESS
!=
fmGetFuncInfo
(
pCxt
->
fmgt
,
pFunc
->
functionName
,
&
pFunc
->
funcId
,
&
pFunc
->
funcType
))
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_INVALID_FUNTION
,
pFunc
->
functionName
);
return
false
;
return
DEAL_RES_ERROR
;
}
int32_t
code
=
fmGetFuncResultType
(
pFunc
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
generateSyntaxErrMsg
(
pCxt
,
code
,
pFunc
->
functionName
);
return
false
;
return
DEAL_RES_ERROR
;
}
if
(
fmIsAggFunc
(
pFunc
->
funcId
)
&&
afterGroupBy
(
pCxt
->
currClause
))
{
if
(
fmIsAggFunc
(
pFunc
->
funcId
)
&&
beforeHaving
(
pCxt
->
currClause
))
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
);
return
false
;
return
DEAL_RES_ERROR
;
}
return
true
;
return
DEAL_RES_CONTINUE
;
}
static
EDealRes
translateExprSubquery
(
STranslateContext
*
pCxt
,
SNode
*
pNode
)
{
return
(
TSDB_CODE_SUCCESS
==
translateSubquery
(
pCxt
,
pNode
)
?
DEAL_RES_CONTINUE
:
DEAL_RES_ERROR
);
}
static
bool
doTranslateExpr
(
SNode
*
pNode
,
void
*
pContext
)
{
static
EDealRes
doTranslateExpr
(
SNode
*
pNode
,
void
*
pContext
)
{
STranslateContext
*
pCxt
=
(
STranslateContext
*
)
pContext
;
switch
(
nodeType
(
pNode
))
{
case
QUERY_NODE_COLUMN
:
...
...
@@ -625,11 +630,11 @@ static bool doTranslateExpr(SNode* pNode, void* pContext) {
case
QUERY_NODE_FUNCTION
:
return
translateFunction
(
pCxt
,
(
SFunctionNode
*
)
pNode
);
case
QUERY_NODE_TEMP_TABLE
:
return
translateSubquery
(
pCxt
,
((
STempTableNode
*
)
pNode
)
->
pSubquery
);
return
translate
Expr
Subquery
(
pCxt
,
((
STempTableNode
*
)
pNode
)
->
pSubquery
);
default:
break
;
}
return
true
;
return
DEAL_RES_CONTINUE
;
}
static
int32_t
translateExpr
(
STranslateContext
*
pCxt
,
SNode
*
pNode
)
{
...
...
@@ -642,6 +647,41 @@ static int32_t translateExprList(STranslateContext* pCxt, SNodeList* pList) {
return
pCxt
->
errCode
;
}
static
bool
isAliasColumn
(
SColumnNode
*
pCol
)
{
return
(
'\0'
==
pCol
->
tableAlias
[
0
]);
}
static
EDealRes
doCheckkExprForGroupBy
(
SNode
*
pNode
,
void
*
pContext
)
{
STranslateContext
*
pCxt
=
(
STranslateContext
*
)
pContext
;
if
(
!
nodesIsExprNode
(
pNode
)
||
(
QUERY_NODE_COLUMN
==
nodeType
(
pNode
)
&&
isAliasColumn
((
SColumnNode
*
)
pNode
)))
{
return
DEAL_RES_CONTINUE
;
}
if
(
QUERY_NODE_FUNCTION
==
nodeType
(
pNode
)
&&
fmIsAggFunc
(((
SFunctionNode
*
)
pNode
)
->
funcId
))
{
return
DEAL_RES_IGNORE_CHILD
;
}
SNode
*
pGroupNode
;
FOREACH
(
pGroupNode
,
pCxt
->
pCurrStmt
->
pGroupByList
)
{
if
(
nodesEqualNode
(
nodesListGetNode
(((
SGroupingSetNode
*
)
pGroupNode
)
->
pParameterList
,
0
),
pNode
))
{
return
DEAL_RES_IGNORE_CHILD
;
}
}
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pNode
))
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
);
return
DEAL_RES_ERROR
;
}
return
DEAL_RES_CONTINUE
;
}
static
int32_t
checkExprForGroupBy
(
STranslateContext
*
pCxt
,
SNode
*
pNode
)
{
nodesWalkNode
(
pNode
,
doCheckkExprForGroupBy
,
pCxt
);
return
pCxt
->
errCode
;
}
static
int32_t
checkExprListForGroupBy
(
STranslateContext
*
pCxt
,
SNodeList
*
pList
)
{
nodesWalkList
(
pList
,
doCheckkExprForGroupBy
,
pCxt
);
return
pCxt
->
errCode
;
}
static
int32_t
translateTable
(
STranslateContext
*
pCxt
,
SNode
*
pTable
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
switch
(
nodeType
(
pTable
))
{
...
...
@@ -732,12 +772,13 @@ static bool translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjec
*
pOther
=
false
;
SNode
*
pNode
;
FOREACH
(
pNode
,
pOrderByList
)
{
if
(
QUERY_NODE_VALUE
==
nodeType
(
pNode
))
{
SValueNode
*
pVal
=
(
SValueNode
*
)
pNode
;
if
(
translateValue
(
pCxt
,
pVal
))
{
SNode
*
pExpr
=
((
SOrderByExprNode
*
)
pNode
)
->
pExpr
;
if
(
QUERY_NODE_VALUE
==
nodeType
(
pExpr
))
{
SValueNode
*
pVal
=
(
SValueNode
*
)
pExpr
;
if
(
!
translateValue
(
pCxt
,
pVal
))
{
return
false
;
}
int32_t
pos
=
getPositionValue
((
SValueNode
*
)
p
Node
);
int32_t
pos
=
getPositionValue
((
SValueNode
*
)
p
Expr
);
if
(
pos
<
0
)
{
ERASE_NODE
(
pOrderByList
);
nodesDestroyNode
(
pNode
);
...
...
@@ -747,9 +788,9 @@ static bool translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjec
return
false
;
}
else
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
nodesMakeNode
(
QUERY_NODE_COLUMN
);
setColumnInfoByExpr
(
NULL
,
(
SExprNode
*
)
nodesListGetNode
(
pProjectionList
,
pos
),
pCol
);
REPLACE_NODE
(
pCol
)
;
nodesDestroyNode
(
p
Node
);
setColumnInfoByExpr
(
NULL
,
(
SExprNode
*
)
nodesListGetNode
(
pProjectionList
,
pos
-
1
),
pCol
);
((
SOrderByExprNode
*
)
pNode
)
->
pExpr
=
(
SNode
*
)
pCol
;
nodesDestroyNode
(
p
Expr
);
}
}
else
{
*
pOther
=
true
;
...
...
@@ -758,17 +799,20 @@ static bool translateOrderByPosition(STranslateContext* pCxt, SNodeList* pProjec
return
true
;
}
static
int32_t
translateOrderBy
(
STranslateContext
*
pCxt
,
S
NodeList
*
pProjectionList
,
SNodeList
*
pOrderByLis
t
)
{
static
int32_t
translateOrderBy
(
STranslateContext
*
pCxt
,
S
SelectStmt
*
pSelec
t
)
{
bool
other
;
if
(
!
translateOrderByPosition
(
pCxt
,
p
ProjectionList
,
pOrderByList
,
&
other
))
{
if
(
!
translateOrderByPosition
(
pCxt
,
p
Select
->
pProjectionList
,
pSelect
->
pOrderByList
,
&
other
))
{
return
pCxt
->
errCode
;
}
if
(
!
other
)
{
return
TSDB_CODE_SUCCESS
;
}
pCxt
->
currClause
=
SQL_CLAUSE_ORDER_BY
;
pCxt
->
pExt
=
pProjectionList
;
return
translateExprList
(
pCxt
,
pOrderByList
);
int32_t
code
=
translateExprList
(
pCxt
,
pSelect
->
pOrderByList
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pSelect
->
pGroupByList
)
{
code
=
checkExprListForGroupBy
(
pCxt
,
pSelect
->
pOrderByList
);
}
return
code
;
}
static
int32_t
translateSelectList
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
...
...
@@ -778,12 +822,22 @@ static int32_t translateSelectList(STranslateContext* pCxt, SSelectStmt* pSelect
pCxt
->
currClause
=
SQL_CLAUSE_SELECT
;
code
=
translateExprList
(
pCxt
,
pSelect
->
pProjectionList
);
}
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pSelect
->
pGroupByList
)
{
code
=
checkExprListForGroupBy
(
pCxt
,
pSelect
->
pProjectionList
);
}
return
code
;
}
static
int32_t
translateHaving
(
STranslateContext
*
pCxt
,
SNode
*
pHaving
)
{
static
int32_t
translateHaving
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
if
(
NULL
==
pSelect
->
pGroupByList
&&
NULL
!=
pSelect
->
pHaving
)
{
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
);
}
pCxt
->
currClause
=
SQL_CLAUSE_HAVING
;
return
translateExpr
(
pCxt
,
pHaving
);
int32_t
code
=
translateExpr
(
pCxt
,
pSelect
->
pHaving
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
checkExprForGroupBy
(
pCxt
,
pSelect
->
pHaving
);
}
return
code
;
}
static
int32_t
translateGroupBy
(
STranslateContext
*
pCxt
,
SNodeList
*
pGroupByList
)
{
...
...
@@ -818,8 +872,8 @@ static int32_t translateFrom(STranslateContext* pCxt, SNode* pTable) {
// } SSelectStmt;
static
int32_t
translateSelect
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
code
=
translateFrom
(
pCxt
,
pSelect
->
pFromTable
);
pCxt
->
pCurrStmt
=
pSelect
;
int32_t
code
=
translateFrom
(
pCxt
,
pSelect
->
pFromTable
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
translateWhere
(
pCxt
,
pSelect
->
pWhere
);
}
...
...
@@ -833,15 +887,14 @@ static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
code
=
translateGroupBy
(
pCxt
,
pSelect
->
pGroupByList
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
translateHaving
(
pCxt
,
pSelect
->
pHaving
);
code
=
translateHaving
(
pCxt
,
pSelect
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
translateSelectList
(
pCxt
,
pSelect
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
translateOrderBy
(
pCxt
,
pSelect
->
pProjectionList
,
pSelect
->
pOrderByList
);
code
=
translateOrderBy
(
pCxt
,
pSelect
);
}
// printf("%s:%d code = %d\n", __FUNCTION__, __LINE__, code);
return
code
;
}
...
...
@@ -860,11 +913,11 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) {
static
int32_t
translateSubquery
(
STranslateContext
*
pCxt
,
SNode
*
pNode
)
{
++
(
pCxt
->
currLevel
);
ESqlClause
currClause
=
pCxt
->
currClause
;
void
*
pExt
=
pCxt
->
pEx
t
;
SSelectStmt
*
pCurrStmt
=
pCxt
->
pCurrStm
t
;
int32_t
code
=
translateQuery
(
pCxt
,
pNode
);
--
(
pCxt
->
currLevel
);
pCxt
->
currClause
=
currClause
;
pCxt
->
p
Ext
=
pEx
t
;
pCxt
->
p
CurrStmt
=
pCurrStm
t
;
return
code
;
}
...
...
source/libs/parser/src/ttokenizer.c
浏览文件 @
a5e9d8f5
...
...
@@ -227,7 +227,9 @@ static SKeyword keywordTable[] = {
{
"OUTPUTTYPE"
,
TK_OUTPUTTYPE
},
{
"AGGREGATE"
,
TK_AGGREGATE
},
{
"BUFSIZE"
,
TK_BUFSIZE
},
{
"PORT"
,
TK_PORT
},
{
"PORT"
,
TK_PORT
},
{
"INNER"
,
NEW_TK_INNER
},
{
"ON"
,
NEW_TK_ON
},
};
static
const
char
isIdChar
[]
=
{
...
...
source/libs/parser/test/newParserTest.cpp
浏览文件 @
a5e9d8f5
...
...
@@ -53,8 +53,8 @@ protected:
code
=
doTranslate
(
&
cxt_
,
&
query_
);
// cout << "doTranslate return " << code << endl;
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
cout
<<
"sql:["
<<
cxt_
.
pSql
<<
"] code:"
<<
tstrerror
(
code
)
<<
", msg:"
<<
errMagBuf_
<<
endl
;
return
(
TSDB_CODE_SUCCESS
!
=
translateCode
);
cout
<<
"sql:["
<<
cxt_
.
pSql
<<
"] code:"
<<
code
<<
", "
<<
translateCode
<<
", msg:"
<<
errMagBuf_
<<
endl
;
return
(
code
=
=
translateCode
);
}
if
(
NULL
!=
query_
.
pRoot
&&
QUERY_NODE_SELECT_STMT
==
nodeType
(
query_
.
pRoot
))
{
cout
<<
"input sql : ["
<<
cxt_
.
pSql
<<
"]"
<<
endl
;
...
...
@@ -71,6 +71,24 @@ protected:
private:
static
const
int
max_err_len
=
1024
;
void
exprNodeToStr
(
const
SNode
*
node
,
string
&
str
,
bool
isProject
)
{
switch
(
nodeType
(
node
))
{
case
QUERY_NODE_COLUMN
:
case
QUERY_NODE_VALUE
:
case
QUERY_NODE_OPERATOR
:
case
QUERY_NODE_FUNCTION
:
{
SExprNode
*
pExpr
=
(
SExprNode
*
)
node
;
str
.
append
(
" ["
+
dataTypeToStr
(
pExpr
->
resType
)
+
"]"
);
if
(
isProject
)
{
str
.
append
(
" AS "
+
string
(
pExpr
->
aliasName
));
}
break
;
}
default:
break
;
}
}
string
dataTypeToStr
(
const
SDataType
&
dt
)
{
switch
(
dt
.
type
)
{
case
TSDB_DATA_TYPE_NULL
:
...
...
@@ -119,7 +137,7 @@ private:
return
"Unknown Data Type "
+
to_string
(
dt
.
type
);
}
void
valueNodeToStr
(
const
SValueNode
*
pVal
,
string
&
str
,
bool
isProject
)
{
void
valueNodeToStr
(
const
SValueNode
*
pVal
,
string
&
str
)
{
switch
(
pVal
->
node
.
resType
.
type
)
{
case
TSDB_DATA_TYPE_NULL
:
str
.
append
(
"null"
);
...
...
@@ -160,10 +178,41 @@ private:
default:
break
;
}
str
.
append
(
" ["
+
dataTypeToStr
(
pVal
->
node
.
resType
)
+
"]"
);
if
(
isProject
)
{
str
.
append
(
" AS "
+
string
(
pVal
->
node
.
aliasName
));
}
void
columnNodeToStr
(
const
SColumnNode
*
pCol
,
string
&
str
)
{
if
(
'\0'
!=
pCol
->
dbName
[
0
])
{
str
.
append
(
pCol
->
dbName
);
str
.
append
(
"."
);
}
if
(
'\0'
!=
pCol
->
tableAlias
[
0
])
{
str
.
append
(
pCol
->
tableAlias
);
str
.
append
(
"."
);
}
str
.
append
(
pCol
->
colName
);
}
void
operatorToStr
(
const
SOperatorNode
*
pOp
,
string
&
str
)
{
nodeToStr
(
pOp
->
pLeft
,
str
,
false
);
str
.
append
(
opTypeToStr
(
pOp
->
opType
));
nodeToStr
(
pOp
->
pRight
,
str
,
false
);
}
void
functionToStr
(
const
SFunctionNode
*
pFunc
,
string
&
str
)
{
str
.
append
(
pFunc
->
functionName
);
str
.
append
(
"("
);
nodeListToStr
(
pFunc
->
pParameterList
,
""
,
str
,
false
,
", "
);
str
.
append
(
")"
);
}
void
groupingSetToStr
(
SGroupingSetNode
*
pGroup
,
string
&
str
)
{
nodeToStr
(
nodesListGetNode
(
pGroup
->
pParameterList
,
0
),
str
,
false
);
}
void
orderByExprToStr
(
SOrderByExprNode
*
pOrderBy
,
string
&
str
)
{
nodeToStr
(
pOrderBy
->
pExpr
,
str
,
false
);
str
.
append
((
ORDER_ASC
==
pOrderBy
->
order
?
" ASC"
:
" DESC"
));
str
.
append
((
NULL_ORDER_FIRST
==
pOrderBy
->
nullOrder
?
" NULLS FIRST"
:
" NULLS LAST"
));
}
void
nodeToStr
(
const
SNode
*
node
,
string
&
str
,
bool
isProject
)
{
...
...
@@ -173,48 +222,41 @@ private:
switch
(
nodeType
(
node
))
{
case
QUERY_NODE_COLUMN
:
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
node
;
if
(
'\0'
!=
pCol
->
dbName
[
0
])
{
str
.
append
(
pCol
->
dbName
);
str
.
append
(
"."
);
}
if
(
'\0'
!=
pCol
->
tableAlias
[
0
])
{
str
.
append
(
pCol
->
tableAlias
);
str
.
append
(
"."
);
}
str
.
append
(
pCol
->
colName
);
str
.
append
(
" ["
+
dataTypeToStr
(
pCol
->
node
.
resType
)
+
"]"
);
if
(
isProject
)
{
str
.
append
(
" AS "
+
string
(
pCol
->
node
.
aliasName
));
}
columnNodeToStr
((
SColumnNode
*
)
node
,
str
);
break
;
}
case
QUERY_NODE_VALUE
:
{
valueNodeToStr
((
SValueNode
*
)
node
,
str
,
isProject
);
valueNodeToStr
((
SValueNode
*
)
node
,
str
);
break
;
}
case
QUERY_NODE_OPERATOR
:
{
SOperatorNode
*
pOp
=
(
SOperatorNode
*
)
node
;
nodeToStr
(
pOp
->
pLeft
,
str
,
false
);
str
.
append
(
opTypeToStr
(
pOp
->
opType
));
nodeToStr
(
pOp
->
pRight
,
str
,
false
);
str
.
append
(
" ["
+
dataTypeToStr
(
pOp
->
node
.
resType
)
+
"]"
);
if
(
isProject
)
{
str
.
append
(
" AS "
+
string
(
pOp
->
node
.
aliasName
));
}
operatorToStr
((
SOperatorNode
*
)
node
,
str
);
break
;
}
case
QUERY_NODE_FUNCTION
:
{
functionToStr
((
SFunctionNode
*
)
node
,
str
);
break
;
}
case
QUERY_NODE_GROUPING_SET
:
{
groupingSetToStr
((
SGroupingSetNode
*
)
node
,
str
);
break
;
}
case
QUERY_NODE_ORDER_BY_EXPR
:
{
orderByExprToStr
((
SOrderByExprNode
*
)
node
,
str
);
break
;
}
default:
break
;
}
exprNodeToStr
(
node
,
str
,
isProject
);
}
void
nodeListToStr
(
const
SNodeList
*
nodelist
,
const
string
&
prefix
,
string
&
str
,
bool
isProject
=
false
)
{
void
nodeListToStr
(
const
SNodeList
*
nodelist
,
const
string
&
prefix
,
string
&
str
,
bool
isProject
=
false
,
const
string
&
sep
=
string
(
"
\n
"
)
)
{
SNode
*
node
=
nullptr
;
FOREACH
(
node
,
nodelist
)
{
str
.
append
(
prefix
);
nodeToStr
(
node
,
str
,
isProject
);
str
.
append
(
"
\n
"
);
str
.
append
(
sep
);
}
}
...
...
@@ -265,8 +307,20 @@ private:
}
str
.
append
(
"
\n
"
);
nodeListToStr
(
select
->
pProjectionList
,
prefix
+
"
\t
"
,
str
,
true
);
str
.
append
(
"
\n
"
+
prefix
+
"FROM
\n
"
);
str
.
append
(
prefix
+
"FROM
\n
"
);
tableToStr
(
select
->
pFromTable
,
prefix
+
"
\t
"
,
str
);
if
(
nullptr
!=
select
->
pWhere
)
{
str
.
append
(
"
\n
"
+
prefix
+
"WHERE
\n\t
"
);
nodeToStr
(
select
->
pWhere
,
str
,
false
);
}
if
(
nullptr
!=
select
->
pGroupByList
)
{
str
.
append
(
"
\n
"
+
prefix
+
"GROUP BY
\n
"
);
nodeListToStr
(
select
->
pGroupByList
,
prefix
+
"
\t
"
,
str
,
true
);
}
if
(
nullptr
!=
select
->
pOrderByList
)
{
str
.
append
(
prefix
+
"ORDER BY
\n
"
);
nodeListToStr
(
select
->
pOrderByList
,
prefix
+
"
\t
"
,
str
,
true
);
}
}
void
selectToSql
(
const
SNode
*
node
,
string
&
sql
)
{
...
...
@@ -332,15 +386,23 @@ private:
case
OP_TYPE_SUB
:
return
" - "
;
case
OP_TYPE_MULTI
:
return
" * "
;
case
OP_TYPE_DIV
:
return
" / "
;
case
OP_TYPE_MOD
:
return
" % "
;
case
OP_TYPE_GREATER_THAN
:
return
" > "
;
case
OP_TYPE_GREATER_EQUAL
:
return
" >= "
;
case
OP_TYPE_LOWER_THAN
:
return
" < "
;
case
OP_TYPE_LOWER_EQUAL
:
return
" <= "
;
case
OP_TYPE_EQUAL
:
return
" = "
;
case
OP_TYPE_NOT_EQUAL
:
return
" != "
;
case
OP_TYPE_IN
:
case
OP_TYPE_NOT_IN
:
case
OP_TYPE_LIKE
:
...
...
@@ -454,6 +516,23 @@ TEST_F(NewParserTest, selectExpression) {
TEST_F
(
NewParserTest
,
selectClause
)
{
setDatabase
(
"root"
,
"test"
);
// GROUP BY clause
bind
(
"SELECT count(*), c2 cnt FROM t1 WHERE c1 > 0"
);
ASSERT_TRUE
(
run
());
bind
(
"SELECT count(*), c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2"
);
ASSERT_TRUE
(
run
());
bind
(
"SELECT count(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 HAVING count(c1) > 10"
);
ASSERT_TRUE
(
run
());
bind
(
"SELECT count(*), c1, c2 + 10, c1 + c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2, c1"
);
ASSERT_TRUE
(
run
());
bind
(
"SELECT count(*), c1 + 10, c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c1 + 10, c2"
);
ASSERT_TRUE
(
run
());
// ORDER BY clause
bind
(
"SELECT count(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 ORDER BY cnt"
);
ASSERT_TRUE
(
run
());
...
...
@@ -480,15 +559,65 @@ TEST_F(NewParserTest, selectSyntaxError) {
TEST_F
(
NewParserTest
,
selectSemanticError
)
{
setDatabase
(
"root"
,
"test"
);
// TSDB_CODE_PAR_INVALID_COLUMN
bind
(
"SELECT c1, c3 FROM t1"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_INVALID_COLUMN
));
bind
(
"SELECT t1.c1, t1.c3 FROM t1"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_INVALID_COLUMN
));
// TSDB_CODE_PAR_TABLE_NOT_EXIST
bind
(
"SELECT * FROM t10"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_
FAILED
));
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_
PAR_TABLE_NOT_EXIST
));
bind
(
"SELECT
c1, c3 FROM t1
"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_
FAILED
));
bind
(
"SELECT
* FROM test.t10
"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_
PAR_TABLE_NOT_EXIST
));
// TSDB_CODE_PAR_AMBIGUOUS_COLUMN
bind
(
"SELECT c2 FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_FAILED
));
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_AMBIGUOUS_COLUMN
));
// TSDB_CODE_PAR_WRONG_VALUE_TYPE
bind
(
"SELECT 10n FROM t1"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
));
bind
(
"SELECT TIMESTAMP '2010' FROM t1"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
));
// TSDB_CODE_PAR_INVALID_FUNTION
bind
(
"SELECT cnt(*) FROM t1"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_INVALID_FUNTION
));
// TSDB_CODE_PAR_FUNTION_PARA_NUM
// TSDB_CODE_PAR_FUNTION_PARA_TYPE
// TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
bind
(
"SELECT c2 FROM t1 tt1 JOIN t1 tt2 ON count(*) > 0"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
));
bind
(
"SELECT c2 FROM t1 where count(*) > 0"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_FAILED
));
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
));
bind
(
"SELECT c2 FROM t1 GROUP BY count(*)"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
));
// TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT
bind
(
"SELECT c2 FROM t1 ORDER BY 0"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT
));
bind
(
"SELECT c2 FROM t1 ORDER BY 2"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT
));
//TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
bind
(
"SELECT count(*) cnt FROM t1 HAVING c1 > 0"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
));
bind
(
"SELECT count(*) cnt FROM t1 GROUP BY c2 HAVING c1 > 0"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
));
bind
(
"SELECT count(*), c1 cnt FROM t1 GROUP BY c2 HAVING c2 > 0"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
));
bind
(
"SELECT count(*) cnt FROM t1 GROUP BY c2 HAVING c2 > 0 ORDER BY c1"
);
ASSERT_TRUE
(
run
(
TSDB_CODE_SUCCESS
,
TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
));
}
source/nodes/src/nodesTraverseFuncs.c
浏览文件 @
a5e9d8f5
...
...
@@ -20,18 +20,22 @@ typedef enum ETraversalOrder {
TRAVERSAL_POSTORDER
}
ETraversalOrder
;
static
bool
walkList
(
SNodeList
*
pNodeList
,
ETraversalOrder
order
,
FQueryNodeWalker
walker
,
void
*
pContext
);
static
EDealRes
walkList
(
SNodeList
*
pNodeList
,
ETraversalOrder
order
,
FQueryNodeWalker
walker
,
void
*
pContext
);
static
bool
walkNode
(
SNode
*
pNode
,
ETraversalOrder
order
,
FQueryNodeWalker
walker
,
void
*
pContext
)
{
static
EDealRes
walkNode
(
SNode
*
pNode
,
ETraversalOrder
order
,
FQueryNodeWalker
walker
,
void
*
pContext
)
{
if
(
NULL
==
pNode
)
{
return
true
;
return
DEAL_RES_CONTINUE
;
}
if
(
TRAVERSAL_PREORDER
==
order
&&
!
walker
(
pNode
,
pContext
))
{
return
false
;
EDealRes
res
=
DEAL_RES_CONTINUE
;
if
(
TRAVERSAL_PREORDER
==
order
)
{
res
=
walker
(
pNode
,
pContext
);
if
(
DEAL_RES_CONTINUE
!=
res
)
{
return
res
;
}
}
bool
res
=
true
;
switch
(
nodeType
(
pNode
))
{
case
QUERY_NODE_COLUMN
:
case
QUERY_NODE_VALUE
:
...
...
@@ -41,7 +45,7 @@ static bool walkNode(SNode* pNode, ETraversalOrder order, FQueryNodeWalker walke
case
QUERY_NODE_OPERATOR
:
{
SOperatorNode
*
pOpNode
=
(
SOperatorNode
*
)
pNode
;
res
=
walkNode
(
pOpNode
->
pLeft
,
order
,
walker
,
pContext
);
if
(
res
)
{
if
(
DEAL_RES_ERROR
!=
res
)
{
res
=
walkNode
(
pOpNode
->
pRight
,
order
,
walker
,
pContext
);
}
break
;
...
...
@@ -61,10 +65,10 @@ static bool walkNode(SNode* pNode, ETraversalOrder order, FQueryNodeWalker walke
case
QUERY_NODE_JOIN_TABLE
:
{
SJoinTableNode
*
pJoinTableNode
=
(
SJoinTableNode
*
)
pNode
;
res
=
walkNode
(
pJoinTableNode
->
pLeft
,
order
,
walker
,
pContext
);
if
(
res
)
{
if
(
DEAL_RES_ERROR
!=
res
)
{
res
=
walkNode
(
pJoinTableNode
->
pRight
,
order
,
walker
,
pContext
);
}
if
(
res
)
{
if
(
DEAL_RES_ERROR
!=
res
)
{
res
=
walkNode
(
pJoinTableNode
->
pOnCond
,
order
,
walker
,
pContext
);
}
break
;
...
...
@@ -84,13 +88,13 @@ static bool walkNode(SNode* pNode, ETraversalOrder order, FQueryNodeWalker walke
case
QUERY_NODE_INTERVAL_WINDOW
:
{
SIntervalWindowNode
*
pInterval
=
(
SIntervalWindowNode
*
)
pNode
;
res
=
walkNode
(
pInterval
->
pInterval
,
order
,
walker
,
pContext
);
if
(
res
)
{
if
(
DEAL_RES_ERROR
!=
res
)
{
res
=
walkNode
(
pInterval
->
pOffset
,
order
,
walker
,
pContext
);
}
if
(
res
)
{
if
(
DEAL_RES_ERROR
!=
res
)
{
res
=
walkNode
(
pInterval
->
pSliding
,
order
,
walker
,
pContext
);
}
if
(
res
)
{
if
(
DEAL_RES_ERROR
!=
res
)
{
res
=
walkNode
(
pInterval
->
pFill
,
order
,
walker
,
pContext
);
}
break
;
...
...
@@ -108,21 +112,21 @@ static bool walkNode(SNode* pNode, ETraversalOrder order, FQueryNodeWalker walke
break
;
}
if
(
res
&&
TRAVERSAL_POSTORDER
==
order
)
{
if
(
DEAL_RES_ERROR
!=
res
&&
TRAVERSAL_POSTORDER
==
order
)
{
res
=
walker
(
pNode
,
pContext
);
}
return
res
;
}
static
bool
walkList
(
SNodeList
*
pNodeList
,
ETraversalOrder
order
,
FQueryNodeWalker
walker
,
void
*
pContext
)
{
static
EDealRes
walkList
(
SNodeList
*
pNodeList
,
ETraversalOrder
order
,
FQueryNodeWalker
walker
,
void
*
pContext
)
{
SNode
*
node
;
FOREACH
(
node
,
pNodeList
)
{
if
(
!
walkNode
(
node
,
order
,
walker
,
pContext
))
{
return
false
;
if
(
DEAL_RES_ERROR
==
walkNode
(
node
,
order
,
walker
,
pContext
))
{
return
DEAL_RES_ERROR
;
}
}
return
true
;
return
DEAL_RES_CONTINUE
;
}
void
nodesWalkNode
(
SNode
*
pNode
,
FQueryNodeWalker
walker
,
void
*
pContext
)
{
...
...
@@ -140,7 +144,3 @@ void nodesWalkNodePostOrder(SNode* pNode, FQueryNodeWalker walker, void* pContex
void
nodesWalkListPostOrder
(
SNodeList
*
pList
,
FQueryNodeWalker
walker
,
void
*
pContext
)
{
(
void
)
walkList
(
pList
,
TRAVERSAL_POSTORDER
,
walker
,
pContext
);
}
bool
nodesWalkStmt
(
SNode
*
pNode
,
FQueryNodeWalker
walker
,
void
*
pContext
)
{
}
source/nodes/src/nodesUtilFuncs.c
浏览文件 @
a5e9d8f5
...
...
@@ -76,7 +76,7 @@ SNode* nodesMakeNode(ENodeType type) {
return
NULL
;
}
static
bool
destroyNode
(
SNode
*
pNode
,
void
*
pContext
)
{
static
EDealRes
destroyNode
(
SNode
*
pNode
,
void
*
pContext
)
{
switch
(
nodeType
(
pNode
))
{
case
QUERY_NODE_VALUE
:
tfree
(((
SValueNode
*
)
pNode
)
->
literal
);
...
...
@@ -85,6 +85,7 @@ static bool destroyNode(SNode* pNode, void* pContext) {
break
;
}
tfree
(
pNode
);
return
DEAL_RES_CONTINUE
;
}
void
nodesDestroyNode
(
SNode
*
pNode
)
{
...
...
@@ -116,9 +117,23 @@ SNodeList* nodesListAppend(SNodeList* pList, SNode* pNode) {
pList
->
pTail
->
pNext
=
p
;
}
pList
->
pTail
=
p
;
++
(
pList
->
length
);
return
pList
;
}
SListCell
*
nodesListErase
(
SNodeList
*
pList
,
SListCell
*
pCell
)
{
if
(
NULL
==
pCell
->
pPrev
)
{
pList
->
pHead
=
pCell
->
pNext
;
}
else
{
pCell
->
pPrev
->
pNext
=
pCell
->
pNext
;
pCell
->
pNext
->
pPrev
=
pCell
->
pPrev
;
}
SListCell
*
pNext
=
pCell
->
pNext
;
tfree
(
pCell
);
--
(
pList
->
length
);
return
pNext
;
}
SNode
*
nodesListGetNode
(
SNodeList
*
pList
,
int32_t
index
)
{
SNode
*
node
;
FOREACH
(
node
,
pList
)
{
...
...
@@ -137,6 +152,11 @@ void nodesDestroyList(SNodeList* pList) {
tfree
(
pList
);
}
bool
nodesIsExprNode
(
const
SNode
*
pNode
)
{
ENodeType
type
=
nodeType
(
pNode
);
return
(
QUERY_NODE_COLUMN
==
type
||
QUERY_NODE_VALUE
==
type
||
QUERY_NODE_OPERATOR
==
type
||
QUERY_NODE_FUNCTION
==
type
);
}
bool
nodesIsArithmeticOp
(
const
SOperatorNode
*
pOp
)
{
switch
(
pOp
->
opType
)
{
case
OP_TYPE_ADD
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录