Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
fb3bd53e
T
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
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看板
提交
fb3bd53e
编写于
2月 11, 2022
作者:
X
Xiaoyu Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
TD-13495 planner refactoring
上级
2b38bed1
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
348 addition
and
135 deletion
+348
-135
include/libs/nodes/nodes.h
include/libs/nodes/nodes.h
+1
-1
include/libs/nodes/querynodes.h
include/libs/nodes/querynodes.h
+23
-2
include/util/taoserror.h
include/util/taoserror.h
+0
-1
source/libs/nodes/src/nodesTraverseFuncs.c
source/libs/nodes/src/nodesTraverseFuncs.c
+57
-0
source/libs/nodes/src/nodesUtilFuncs.c
source/libs/nodes/src/nodesUtilFuncs.c
+104
-6
source/libs/parser/src/astCreateFuncs.c
source/libs/parser/src/astCreateFuncs.c
+8
-2
source/libs/parser/src/parserImpl.c
source/libs/parser/src/parserImpl.c
+9
-20
source/libs/planner/inc/plannerImpl.h
source/libs/planner/inc/plannerImpl.h
+1
-0
source/libs/planner/src/plannerImpl.c
source/libs/planner/src/plannerImpl.c
+145
-103
未找到文件。
include/libs/nodes/nodes.h
浏览文件 @
fb3bd53e
...
...
@@ -100,7 +100,7 @@ SNode* nodesMakeNode(ENodeType type);
void
nodesDestroyNode
(
SNode
*
pNode
);
SNodeList
*
nodesMakeList
();
SNodeList
*
nodesListAppend
(
SNodeList
*
pList
,
SNode
*
pNode
);
int32_t
nodesListAppend
(
SNodeList
*
pList
,
SNode
*
pNode
);
SListCell
*
nodesListErase
(
SNodeList
*
pList
,
SListCell
*
pCell
);
SNode
*
nodesListGetNode
(
SNodeList
*
pList
,
int32_t
index
);
void
nodesDestroyList
(
SNodeList
*
pList
);
...
...
include/libs/nodes/querynodes.h
浏览文件 @
fb3bd53e
...
...
@@ -50,6 +50,7 @@ typedef enum EColumnType {
typedef
struct
SColumnNode
{
SExprNode
node
;
// QUERY_NODE_COLUMN
uint64_t
tableId
;
int16_t
colId
;
EColumnType
colType
;
// column or tag
char
dbName
[
TSDB_DB_NAME_LEN
];
...
...
@@ -59,10 +60,11 @@ typedef struct SColumnNode {
SNode
*
pProjectRef
;
}
SColumnNode
;
typedef
struct
SColumnRef
{
typedef
struct
SColumnRef
Node
{
ENodeType
type
;
int32_t
tupleId
;
int32_t
slotId
;
}
SColumnRef
;
}
SColumnRef
Node
;
typedef
struct
SValueNode
{
SExprNode
node
;
// QUERY_NODE_VALUE
...
...
@@ -269,6 +271,25 @@ typedef struct SSetOperator {
SNode
*
pLimit
;
}
SSetOperator
;
typedef
enum
ESqlClause
{
SQL_CLAUSE_FROM
=
1
,
SQL_CLAUSE_WHERE
,
SQL_CLAUSE_PARTITION_BY
,
SQL_CLAUSE_WINDOW
,
SQL_CLAUSE_GROUP_BY
,
SQL_CLAUSE_HAVING
,
SQL_CLAUSE_SELECT
,
SQL_CLAUSE_ORDER_BY
}
ESqlClause
;
void
nodesWalkSelectStmt
(
SSelectStmt
*
pSelect
,
ESqlClause
clause
,
FNodeWalker
walker
,
void
*
pContext
);
void
nodesRewriteSelectStmt
(
SSelectStmt
*
pSelect
,
ESqlClause
clause
,
FNodeRewriter
rewriter
,
void
*
pContext
);
int32_t
nodesCollectColumns
(
SSelectStmt
*
pSelect
,
ESqlClause
clause
,
uint64_t
tableId
,
bool
realCol
,
SNodeList
**
pCols
);
typedef
bool
(
*
FFuncClassifier
)(
int32_t
funcId
);
int32_t
nodesCollectFuncs
(
SSelectStmt
*
pSelect
,
FFuncClassifier
classifier
,
SNodeList
**
pFuncs
);
bool
nodesIsExprNode
(
const
SNode
*
pNode
);
bool
nodesIsArithmeticOp
(
const
SOperatorNode
*
pOp
);
...
...
include/util/taoserror.h
浏览文件 @
fb3bd53e
...
...
@@ -459,7 +459,6 @@ int32_t* taosGetErrno();
#define TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION TAOS_DEF_ERROR_CODE(0, 0x260A) //Not a GROUP BY expression
#define TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION TAOS_DEF_ERROR_CODE(0, 0x260B) //Not SELECTed expression
#define TSDB_CODE_PAR_NOT_SINGLE_GROUP TAOS_DEF_ERROR_CODE(0, 0x260C) //Not a single-group group function
#define TSDB_CODE_PAR_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x260D) //Out of memory
#ifdef __cplusplus
}
...
...
source/libs/nodes/src/nodesTraverseFuncs.c
浏览文件 @
fb3bd53e
...
...
@@ -264,3 +264,60 @@ void nodesRewriteNodePostOrder(SNode** pNode, FNodeRewriter rewriter, void* pCon
void
nodesRewriteListPostOrder
(
SNodeList
*
pList
,
FNodeRewriter
rewriter
,
void
*
pContext
)
{
(
void
)
rewriteList
(
pList
,
TRAVERSAL_POSTORDER
,
rewriter
,
pContext
);
}
void
nodesWalkSelectStmt
(
SSelectStmt
*
pSelect
,
ESqlClause
clause
,
FNodeWalker
walker
,
void
*
pContext
)
{
if
(
NULL
==
pSelect
)
{
return
;
}
switch
(
clause
)
{
case
SQL_CLAUSE_FROM
:
nodesWalkNode
(
pSelect
->
pFromTable
,
walker
,
pContext
);
nodesWalkNode
(
pSelect
->
pWhere
,
walker
,
pContext
);
case
SQL_CLAUSE_WHERE
:
nodesWalkList
(
pSelect
->
pPartitionByList
,
walker
,
pContext
);
case
SQL_CLAUSE_PARTITION_BY
:
nodesWalkNode
(
pSelect
->
pWindow
,
walker
,
pContext
);
case
SQL_CLAUSE_WINDOW
:
nodesWalkList
(
pSelect
->
pGroupByList
,
walker
,
pContext
);
case
SQL_CLAUSE_GROUP_BY
:
nodesWalkNode
(
pSelect
->
pHaving
,
walker
,
pContext
);
case
SQL_CLAUSE_HAVING
:
nodesWalkList
(
pSelect
->
pProjectionList
,
walker
,
pContext
);
case
SQL_CLAUSE_SELECT
:
nodesWalkList
(
pSelect
->
pOrderByList
,
walker
,
pContext
);
case
SQL_CLAUSE_ORDER_BY
:
default:
break
;
}
return
;
}
void
nodesRewriteSelectStmt
(
SSelectStmt
*
pSelect
,
ESqlClause
clause
,
FNodeRewriter
rewriter
,
void
*
pContext
)
{
if
(
NULL
==
pSelect
)
{
return
;
}
switch
(
clause
)
{
case
SQL_CLAUSE_FROM
:
nodesRewriteNode
(
&
(
pSelect
->
pFromTable
),
rewriter
,
pContext
);
nodesRewriteNode
(
&
(
pSelect
->
pWhere
),
rewriter
,
pContext
);
case
SQL_CLAUSE_WHERE
:
nodesRewriteList
(
pSelect
->
pPartitionByList
,
rewriter
,
pContext
);
case
SQL_CLAUSE_PARTITION_BY
:
nodesRewriteNode
(
&
(
pSelect
->
pWindow
),
rewriter
,
pContext
);
case
SQL_CLAUSE_WINDOW
:
nodesRewriteList
(
pSelect
->
pGroupByList
,
rewriter
,
pContext
);
case
SQL_CLAUSE_GROUP_BY
:
nodesRewriteNode
(
&
(
pSelect
->
pHaving
),
rewriter
,
pContext
);
case
SQL_CLAUSE_HAVING
:
nodesRewriteList
(
pSelect
->
pProjectionList
,
rewriter
,
pContext
);
case
SQL_CLAUSE_SELECT
:
nodesRewriteList
(
pSelect
->
pOrderByList
,
rewriter
,
pContext
);
default:
break
;
}
return
;
}
source/libs/nodes/src/nodesUtilFuncs.c
浏览文件 @
fb3bd53e
...
...
@@ -15,7 +15,9 @@
#include "querynodes.h"
#include "nodesShowStmts.h"
#include "taos.h"
#include "taoserror.h"
#include "thash.h"
static
SNode
*
makeNode
(
ENodeType
type
,
size_t
size
)
{
SNode
*
p
=
calloc
(
1
,
size
);
...
...
@@ -98,14 +100,14 @@ SNodeList* nodesMakeList() {
return
p
;
}
SNodeList
*
nodesListAppend
(
SNodeList
*
pList
,
SNode
*
pNode
)
{
int32_t
nodesListAppend
(
SNodeList
*
pList
,
SNode
*
pNode
)
{
if
(
NULL
==
pList
||
NULL
==
pNode
)
{
return
NULL
;
return
TSDB_CODE_SUCCESS
;
}
SListCell
*
p
=
calloc
(
1
,
sizeof
(
SListCell
));
if
(
NULL
==
p
)
{
terrno
=
TSDB_CODE_
TSC_
OUT_OF_MEMORY
;
return
pList
;
terrno
=
TSDB_CODE_OUT_OF_MEMORY
;
return
TSDB_CODE_OUT_OF_MEMORY
;
}
p
->
pNode
=
pNode
;
if
(
NULL
==
pList
->
pHead
)
{
...
...
@@ -116,7 +118,7 @@ SNodeList* nodesListAppend(SNodeList* pList, SNode* pNode) {
}
pList
->
pTail
=
p
;
++
(
pList
->
length
);
return
pList
;
return
TSDB_CODE_SUCCESS
;
}
SListCell
*
nodesListErase
(
SNodeList
*
pList
,
SListCell
*
pCell
)
{
...
...
@@ -207,4 +209,100 @@ bool nodesIsTimeorderQuery(const SNode* pQuery) {
bool
nodesIsTimelineQuery
(
const
SNode
*
pQuery
)
{
return
false
;
}
\ No newline at end of file
}
typedef
struct
SCollectColumnsCxt
{
int32_t
errCode
;
uint64_t
tableId
;
bool
realCol
;
SNodeList
*
pCols
;
SHashObj
*
pColIdHash
;
}
SCollectColumnsCxt
;
static
EDealRes
doCollect
(
SCollectColumnsCxt
*
pCxt
,
int32_t
id
,
SNode
*
pNode
)
{
if
(
NULL
==
taosHashGet
(
pCxt
->
pColIdHash
,
&
id
,
sizeof
(
id
)))
{
pCxt
->
errCode
=
taosHashPut
(
pCxt
->
pColIdHash
,
&
id
,
sizeof
(
id
),
NULL
,
0
);
if
(
TSDB_CODE_SUCCESS
==
pCxt
->
errCode
)
{
pCxt
->
errCode
=
nodesListAppend
(
pCxt
->
pCols
,
pNode
);
}
return
(
TSDB_CODE_SUCCESS
==
pCxt
->
errCode
?
DEAL_RES_IGNORE_CHILD
:
DEAL_RES_ERROR
);
}
return
DEAL_RES_CONTINUE
;
}
static
EDealRes
collectColumns
(
SNode
*
pNode
,
void
*
pContext
)
{
SCollectColumnsCxt
*
pCxt
=
(
SCollectColumnsCxt
*
)
pContext
;
if
(
pCxt
->
realCol
&&
QUERY_NODE_COLUMN
==
nodeType
(
pNode
))
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
pNode
;
int32_t
colId
=
pCol
->
colId
;
if
(
pCxt
->
tableId
==
pCol
->
tableId
&&
colId
>
0
)
{
return
doCollect
(
pCxt
,
colId
,
pNode
);
}
}
else
if
(
!
pCxt
->
realCol
&&
QUERY_NODE_COLUMN_REF
==
nodeType
(
pNode
))
{
return
doCollect
(
pCxt
,
((
SColumnRefNode
*
)
pNode
)
->
slotId
,
pNode
);
}
return
DEAL_RES_CONTINUE
;
}
int32_t
nodesCollectColumns
(
SSelectStmt
*
pSelect
,
ESqlClause
clause
,
uint64_t
tableId
,
bool
realCol
,
SNodeList
**
pCols
)
{
if
(
NULL
==
pSelect
||
NULL
==
pCols
)
{
return
TSDB_CODE_SUCCESS
;
}
SCollectColumnsCxt
cxt
=
{
.
errCode
=
TSDB_CODE_SUCCESS
,
.
realCol
=
realCol
,
.
pCols
=
nodesMakeList
(),
.
pColIdHash
=
taosHashInit
(
128
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BIGINT
),
true
,
HASH_NO_LOCK
)
};
if
(
NULL
==
cxt
.
pCols
||
NULL
==
cxt
.
pColIdHash
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
nodesWalkSelectStmt
(
pSelect
,
clause
,
collectColumns
,
&
cxt
);
taosHashCleanup
(
cxt
.
pColIdHash
);
if
(
TSDB_CODE_SUCCESS
!=
cxt
.
errCode
)
{
nodesDestroyList
(
cxt
.
pCols
);
return
cxt
.
errCode
;
}
*
pCols
=
cxt
.
pCols
;
return
TSDB_CODE_SUCCESS
;
}
typedef
struct
SCollectFuncsCxt
{
int32_t
errCode
;
FFuncClassifier
classifier
;
SNodeList
*
pFuncs
;
}
SCollectFuncsCxt
;
static
EDealRes
collectFuncs
(
SNode
*
pNode
,
void
*
pContext
)
{
SCollectFuncsCxt
*
pCxt
=
(
SCollectFuncsCxt
*
)
pContext
;
if
(
QUERY_NODE_FUNCTION
==
nodeType
(
pNode
)
&&
pCxt
->
classifier
(((
SFunctionNode
*
)
pNode
)
->
funcId
))
{
pCxt
->
errCode
=
nodesListAppend
(
pCxt
->
pFuncs
,
pNode
);
return
(
TSDB_CODE_SUCCESS
==
pCxt
->
errCode
?
DEAL_RES_IGNORE_CHILD
:
DEAL_RES_ERROR
);
}
return
DEAL_RES_CONTINUE
;
}
int32_t
nodesCollectFuncs
(
SSelectStmt
*
pSelect
,
FFuncClassifier
classifier
,
SNodeList
**
pFuncs
)
{
if
(
NULL
==
pSelect
||
NULL
==
pFuncs
)
{
return
TSDB_CODE_SUCCESS
;
}
SCollectFuncsCxt
cxt
=
{
.
errCode
=
TSDB_CODE_SUCCESS
,
.
classifier
=
classifier
,
.
pFuncs
=
nodesMakeList
()
};
if
(
NULL
==
cxt
.
pFuncs
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
nodesWalkSelectStmt
(
pSelect
,
SQL_CLAUSE_GROUP_BY
,
collectFuncs
,
&
cxt
);
if
(
TSDB_CODE_SUCCESS
!=
cxt
.
errCode
)
{
nodesDestroyList
(
cxt
.
pFuncs
);
return
cxt
.
errCode
;
}
*
pFuncs
=
cxt
.
pFuncs
;
return
TSDB_CODE_SUCCESS
;
}
source/libs/parser/src/astCreateFuncs.c
浏览文件 @
fb3bd53e
...
...
@@ -96,11 +96,17 @@ SToken getTokenFromRawExprNode(SAstCreateContext* pCxt, SNode* pNode) {
SNodeList
*
createNodeList
(
SAstCreateContext
*
pCxt
,
SNode
*
pNode
)
{
SNodeList
*
list
=
nodesMakeList
();
CHECK_OUT_OF_MEM
(
list
);
return
nodesListAppend
(
list
,
pNode
);
if
(
TSDB_CODE_SUCCESS
!=
nodesListAppend
(
list
,
pNode
))
{
pCxt
->
valid
=
false
;
}
return
list
;
}
SNodeList
*
addNodeToList
(
SAstCreateContext
*
pCxt
,
SNodeList
*
pList
,
SNode
*
pNode
)
{
return
nodesListAppend
(
pList
,
pNode
);
if
(
TSDB_CODE_SUCCESS
!=
nodesListAppend
(
pList
,
pNode
))
{
pCxt
->
valid
=
false
;
}
return
pList
;
}
SNode
*
createColumnNode
(
SAstCreateContext
*
pCxt
,
const
SToken
*
pTableAlias
,
const
SToken
*
pColumnName
)
{
...
...
source/libs/parser/src/parserImpl.c
浏览文件 @
fb3bd53e
...
...
@@ -241,17 +241,6 @@ abort_parse:
return
cxt
.
valid
?
TSDB_CODE_SUCCESS
:
TSDB_CODE_FAILED
;
}
typedef
enum
ESqlClause
{
SQL_CLAUSE_FROM
=
1
,
SQL_CLAUSE_WHERE
,
SQL_CLAUSE_PARTITION_BY
,
SQL_CLAUSE_WINDOW
,
SQL_CLAUSE_GROUP_BY
,
SQL_CLAUSE_HAVING
,
SQL_CLAUSE_SELECT
,
SQL_CLAUSE_ORDER_BY
}
ESqlClause
;
static
bool
afterGroupBy
(
ESqlClause
clause
)
{
return
clause
>
SQL_CLAUSE_GROUP_BY
;
}
...
...
@@ -298,7 +287,7 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return
"Not SELECTed expression"
;
case
TSDB_CODE_PAR_NOT_SINGLE_GROUP
:
return
"Not a single-group group function"
;
case
TSDB_CODE_
PAR_
OUT_OF_MEMORY
:
case
TSDB_CODE_OUT_OF_MEMORY
:
return
"Out of memory"
;
default:
return
"Unknown error"
;
...
...
@@ -376,7 +365,7 @@ static void setColumnInfoBySchema(const STableNode* pTable, const SSchema* pColS
static
void
setColumnInfoByExpr
(
const
STableNode
*
pTable
,
SExprNode
*
pExpr
,
SColumnNode
*
pCol
)
{
pCol
->
pProjectRef
=
(
SNode
*
)
pExpr
;
pExpr
->
pAssociationList
=
nodesListAppend
(
pExpr
->
pAssociationList
,
(
SNode
*
)
pCol
);
nodesListAppend
(
pExpr
->
pAssociationList
,
(
SNode
*
)
pCol
);
if
(
NULL
!=
pTable
)
{
strcpy
(
pCol
->
tableAlias
,
pTable
->
tableAlias
);
}
...
...
@@ -391,7 +380,7 @@ static int32_t createColumnNodeByTable(STranslateContext* pCxt, const STableNode
for
(
int32_t
i
=
0
;
i
<
nums
;
++
i
)
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
nodesMakeNode
(
QUERY_NODE_COLUMN
);
if
(
NULL
==
pCol
)
{
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_
PAR_
OUT_OF_MEMORY
);
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_OUT_OF_MEMORY
);
}
setColumnInfoBySchema
(
pTable
,
pMeta
->
schema
+
i
,
pCol
);
nodesListAppend
(
pList
,
(
SNode
*
)
pCol
);
...
...
@@ -402,7 +391,7 @@ static int32_t createColumnNodeByTable(STranslateContext* pCxt, const STableNode
FOREACH
(
pNode
,
pProjectList
)
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
nodesMakeNode
(
QUERY_NODE_COLUMN
);
if
(
NULL
==
pCol
)
{
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_
PAR_
OUT_OF_MEMORY
);
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_OUT_OF_MEMORY
);
}
setColumnInfoByExpr
(
pTable
,
(
SExprNode
*
)
pNode
,
pCol
);
nodesListAppend
(
pList
,
(
SNode
*
)
pCol
);
...
...
@@ -572,7 +561,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
int32_t
n
=
strlen
(
pVal
->
literal
);
pVal
->
datum
.
p
=
calloc
(
1
,
n
);
if
(
NULL
==
pVal
->
datum
.
p
)
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_
PAR_
OUT_OF_MEMORY
);
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_OUT_OF_MEMORY
);
return
DEAL_RES_ERROR
;
}
trimStringCopy
(
pVal
->
literal
,
n
,
pVal
->
datum
.
p
);
...
...
@@ -582,7 +571,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
int32_t
n
=
strlen
(
pVal
->
literal
);
char
*
tmp
=
calloc
(
1
,
n
);
if
(
NULL
==
tmp
)
{
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_
PAR_
OUT_OF_MEMORY
);
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_OUT_OF_MEMORY
);
return
DEAL_RES_ERROR
;
}
int32_t
len
=
trimStringCopy
(
pVal
->
literal
,
n
,
tmp
);
...
...
@@ -830,7 +819,7 @@ static int32_t translateStar(STranslateContext* pCxt, SSelectStmt* pSelect, bool
size_t
nums
=
taosArrayGetSize
(
pTables
);
pSelect
->
pProjectionList
=
nodesMakeList
();
if
(
NULL
==
pSelect
->
pProjectionList
)
{
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_
PAR_
OUT_OF_MEMORY
);
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_OUT_OF_MEMORY
);
}
for
(
size_t
i
=
0
;
i
<
nums
;
++
i
)
{
STableNode
*
pTable
=
taosArrayGetP
(
pTables
,
i
);
...
...
@@ -897,7 +886,7 @@ static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pPro
}
else
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
nodesMakeNode
(
QUERY_NODE_COLUMN
);
if
(
NULL
==
pCol
)
{
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_
PAR_
OUT_OF_MEMORY
);
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_OUT_OF_MEMORY
);
}
setColumnInfoByExpr
(
NULL
,
(
SExprNode
*
)
nodesListGetNode
(
pProjectionList
,
pos
-
1
),
pCol
);
((
SOrderByExprNode
*
)
pNode
)
->
pExpr
=
(
SNode
*
)
pCol
;
...
...
@@ -1036,7 +1025,7 @@ int32_t setReslutSchema(STranslateContext* pCxt, SQuery* pQuery) {
pQuery
->
numOfResCols
=
LIST_LENGTH
(
pSelect
->
pProjectionList
);
pQuery
->
pResSchema
=
calloc
(
pQuery
->
numOfResCols
,
sizeof
(
SSchema
));
if
(
NULL
==
pQuery
->
pResSchema
)
{
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_
PAR_
OUT_OF_MEMORY
);
return
generateSyntaxErrMsg
(
pCxt
,
TSDB_CODE_OUT_OF_MEMORY
);
}
SNode
*
pNode
;
int32_t
index
=
0
;
...
...
source/libs/planner/inc/plannerImpl.h
浏览文件 @
fb3bd53e
...
...
@@ -25,6 +25,7 @@ extern "C" {
typedef
struct
SLogicNode
{
ENodeType
type
;
int32_t
id
;
SNodeList
*
pTargets
;
SNode
*
pConditions
;
SNodeList
*
pChildren
;
...
...
source/libs/planner/src/plannerImpl.c
浏览文件 @
fb3bd53e
...
...
@@ -16,71 +16,32 @@
#include "plannerImpl.h"
#include "functionMgt.h"
static
SLogicNode
*
createQueryLogicNode
(
SNode
*
pStmt
);
typedef
struct
SCollectColumnsCxt
{
SNodeList
*
pCols
;
SHashObj
*
pColIdHash
;
}
SCollectColumnsCxt
;
static
EDealRes
doCollectColumns
(
SNode
*
pNode
,
void
*
pContext
)
{
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pNode
))
{
SCollectColumnsCxt
*
pCxt
=
(
SCollectColumnsCxt
*
)
pContext
;
int16_t
colId
=
((
SColumnNode
*
)
pNode
)
->
colId
;
if
(
colId
>
0
)
{
if
(
NULL
==
taosHashGet
(
pCxt
->
pColIdHash
,
&
colId
,
sizeof
(
colId
)))
{
taosHashPut
(
pCxt
->
pColIdHash
,
&
colId
,
sizeof
(
colId
),
NULL
,
0
);
nodesListAppend
(
pCxt
->
pCols
,
pNode
);
}
}
}
return
DEAL_RES_CONTINUE
;
}
static
SNodeList
*
collectColumns
(
SSelectStmt
*
pSelect
)
{
SCollectColumnsCxt
cxt
=
{
.
pCols
=
nodesMakeList
(),
.
pColIdHash
=
taosHashInit
(
128
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BIGINT
),
true
,
HASH_NO_LOCK
)
};
if
(
NULL
==
cxt
.
pCols
||
NULL
==
cxt
.
pColIdHash
)
{
return
NULL
;
}
nodesWalkNode
(
pSelect
->
pFromTable
,
doCollectColumns
,
&
cxt
);
nodesWalkNode
(
pSelect
->
pWhere
,
doCollectColumns
,
&
cxt
);
nodesWalkList
(
pSelect
->
pPartitionByList
,
doCollectColumns
,
&
cxt
);
nodesWalkNode
(
pSelect
->
pWindow
,
doCollectColumns
,
&
cxt
);
nodesWalkList
(
pSelect
->
pGroupByList
,
doCollectColumns
,
&
cxt
);
nodesWalkNode
(
pSelect
->
pHaving
,
doCollectColumns
,
&
cxt
);
nodesWalkList
(
pSelect
->
pProjectionList
,
doCollectColumns
,
&
cxt
);
nodesWalkList
(
pSelect
->
pOrderByList
,
doCollectColumns
,
&
cxt
);
taosHashCleanup
(
cxt
.
pColIdHash
);
return
cxt
.
pCols
;
}
typedef
struct
SCollectAggFuncsCxt
{
SNodeList
*
pAggFuncs
;
}
SCollectAggFuncsCxt
;
static
EDealRes
doCollectAggFuncs
(
SNode
*
pNode
,
void
*
pContext
)
{
if
(
QUERY_NODE_FUNCTION
==
nodeType
(
pNode
)
&&
fmIsAggFunc
(((
SFunctionNode
*
)
pNode
)
->
funcId
))
{
SCollectAggFuncsCxt
*
pCxt
=
(
SCollectAggFuncsCxt
*
)
pContext
;
nodesListAppend
(
pCxt
->
pAggFuncs
,
pNode
);
return
DEAL_RES_IGNORE_CHILD
;
}
return
DEAL_RES_CONTINUE
;
}
static
SNodeList
*
collectAggFuncs
(
SSelectStmt
*
pSelect
)
{
SCollectAggFuncsCxt
cxt
=
{
.
pAggFuncs
=
nodesMakeList
()
};
if
(
NULL
==
cxt
.
pAggFuncs
)
{
return
NULL
;
}
nodesWalkNode
(
pSelect
->
pHaving
,
doCollectAggFuncs
,
&
cxt
);
nodesWalkList
(
pSelect
->
pProjectionList
,
doCollectAggFuncs
,
&
cxt
);
if
(
!
pSelect
->
isDistinct
)
{
nodesWalkList
(
pSelect
->
pOrderByList
,
doCollectAggFuncs
,
&
cxt
);
}
return
cxt
.
pAggFuncs
;
}
#define CHECK_ALLOC(p, res) \
do { \
if (NULL == p) { \
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; \
return res; \
} \
} while (0)
#define CHECK_CODE(exec, res) \
do { \
int32_t code = exec; \
if (TSDB_CODE_SUCCESS != code) { \
pCxt->errCode = code; \
return res; \
} \
} while (0)
typedef
struct
SPlanContext
{
int32_t
errCode
;
int32_t
planNodeId
;
SNodeList
*
pResource
;
}
SPlanContext
;
typedef
struct
SRewriteExprCxt
{
int32_t
errCode
;
int32_t
planNodeId
;
SNodeList
*
pTargets
;
}
SRewriteExprCxt
;
...
...
@@ -90,9 +51,15 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
int32_t
index
=
0
;
FOREACH
(
pTarget
,
pCxt
->
pTargets
)
{
if
(
nodesEqualNode
(
pTarget
,
*
pNode
))
{
SColumnRefNode
*
pCol
=
(
SColumnRefNode
*
)
nodesMakeNode
(
QUERY_NODE_COLUMN_REF
);
if
(
NULL
==
pCol
)
{
pCxt
->
errCode
=
TSDB_CODE_OUT_OF_MEMORY
;
return
DEAL_RES_ERROR
;
}
pCol
->
tupleId
=
pCxt
->
planNodeId
;
pCol
->
slotId
=
index
;
nodesDestroyNode
(
*
pNode
);
*
pNode
=
nodesMakeNode
(
QUERY_NODE_COLUMN_REF
);
((
SColumnRef
*
)
*
pNode
)
->
slotId
=
index
;
*
pNode
=
(
SNode
*
)
pCol
;
return
DEAL_RES_IGNORE_CHILD
;
}
++
index
;
...
...
@@ -100,59 +67,93 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
return
DEAL_RES_CONTINUE
;
}
static
int32_t
rewriteExpr
(
SNodeList
*
pTargets
,
SSelectStmt
*
pSelect
)
{
SRewriteExprCxt
cxt
=
{
.
pTargets
=
pTargets
};
nodesRewriteNode
(
&
(
pSelect
->
pFromTable
),
doRewriteExpr
,
&
cxt
);
nodesRewriteNode
(
&
(
pSelect
->
pWhere
),
doRewriteExpr
,
&
cxt
);
nodesRewriteList
(
pSelect
->
pPartitionByList
,
doRewriteExpr
,
&
cxt
);
nodesRewriteNode
(
&
(
pSelect
->
pWindow
),
doRewriteExpr
,
&
cxt
);
nodesRewriteList
(
pSelect
->
pGroupByList
,
doRewriteExpr
,
&
cxt
);
nodesRewriteNode
(
&
(
pSelect
->
pHaving
),
doRewriteExpr
,
&
cxt
);
nodesRewriteList
(
pSelect
->
pProjectionList
,
doRewriteExpr
,
&
cxt
);
nodesRewriteList
(
pSelect
->
pOrderByList
,
doRewriteExpr
,
&
cxt
);
return
TSDB_CODE_SUCCESS
;
static
int32_t
rewriteExpr
(
int32_t
planNodeId
,
SNodeList
*
pTargets
,
SSelectStmt
*
pSelect
,
ESqlClause
clause
)
{
SRewriteExprCxt
cxt
=
{
.
errCode
=
TSDB_CODE_SUCCESS
,
.
planNodeId
=
planNodeId
,
.
pTargets
=
pTargets
};
nodesRewriteSelectStmt
(
pSelect
,
clause
,
doRewriteExpr
,
&
cxt
);
return
cxt
.
errCode
;
}
static
SLogicNode
*
pushLogicNode
(
SLogicNode
*
pRoot
,
SLogicNode
*
pNode
)
{
static
SLogicNode
*
pushLogicNode
(
SPlanContext
*
pCxt
,
SLogicNode
*
pRoot
,
SLogicNode
*
pNode
)
{
if
(
TSDB_CODE_SUCCESS
!=
pCxt
->
errCode
)
{
goto
error
;
}
if
(
NULL
==
pRoot
)
{
return
pNode
;
}
if
(
NULL
==
pNode
)
{
return
pRoot
;
}
pRoot
->
pParent
=
pNode
;
if
(
NULL
==
pNode
->
pChildren
)
{
pNode
->
pChildren
=
nodesMakeList
();
if
(
NULL
==
pNode
->
pChildren
)
{
goto
error
;
}
}
nodesListAppend
(
pNode
->
pChildren
,
(
SNode
*
)
pRoot
);
if
(
TSDB_CODE_SUCCESS
!=
nodesListAppend
(
pNode
->
pChildren
,
(
SNode
*
)
pRoot
))
{
goto
error
;
}
pRoot
->
pParent
=
pNode
;
return
pNode
;
error:
nodesDestroyNode
((
SNode
*
)
pNode
);
return
pRoot
;
}
static
SNodeList
*
createScanTargets
(
SNodeList
*
pCols
)
{
static
SNodeList
*
createScanTargets
(
int32_t
planNodeId
,
int32_t
numOfScanCols
)
{
SNodeList
*
pTargets
=
nodesMakeList
();
if
(
NULL
==
pTargets
)
{
return
NULL
;
}
for
(
int32_t
i
=
0
;
i
<
numOfScanCols
;
++
i
)
{
SColumnRefNode
*
pCol
=
(
SColumnRefNode
*
)
nodesMakeNode
(
QUERY_NODE_COLUMN_REF
);
if
(
NULL
==
pCol
||
TSDB_CODE_SUCCESS
!=
nodesListAppend
(
pTargets
,
(
SNode
*
)
pCol
))
{
nodesDestroyList
(
pTargets
);
return
NULL
;
}
pCol
->
tupleId
=
planNodeId
;
pCol
->
slotId
=
i
;
}
return
pTargets
;
}
static
SLogicNode
*
createScanLogicNode
(
SSelectStmt
*
pSelect
,
SRealTableNode
*
pRealTable
)
{
static
SLogicNode
*
createScanLogicNode
(
S
PlanContext
*
pCxt
,
S
SelectStmt
*
pSelect
,
SRealTableNode
*
pRealTable
)
{
SScanLogicNode
*
pScan
=
(
SScanLogicNode
*
)
nodesMakeNode
(
QUERY_NODE_LOGIC_PLAN_SCAN
);
SNodeList
*
pCols
=
collectColumns
(
pSelect
);
pScan
->
pScanCols
=
nodesCloneList
(
pCols
);
//
rewriteExpr
(
pScan
->
pScanCols
,
pSelect
);
pScan
->
node
.
pTargets
=
createScanTargets
(
pCols
);
CHECK_ALLOC
(
pScan
,
NULL
);
pScan
->
node
.
id
=
pCxt
->
planNodeId
++
;
pScan
->
pMeta
=
pRealTable
->
pMeta
;
// set columns to scan
SNodeList
*
pCols
=
NULL
;
CHECK_CODE
(
nodesCollectColumns
(
pSelect
,
SQL_CLAUSE_FROM
,
pScan
->
pMeta
->
uid
,
true
,
&
pCols
),
(
SLogicNode
*
)
pScan
);
pScan
->
pScanCols
=
nodesCloneList
(
pCols
);
CHECK_ALLOC
(
pScan
->
pScanCols
,
(
SLogicNode
*
)
pScan
);
// pScanCols of SScanLogicNode is equivalent to pTargets of other logic nodes
CHECK_CODE
(
rewriteExpr
(
pScan
->
node
.
id
,
pScan
->
pScanCols
,
pSelect
,
SQL_CLAUSE_FROM
),
(
SLogicNode
*
)
pScan
);
// set output
pScan
->
node
.
pTargets
=
createScanTargets
(
pScan
->
node
.
id
,
LIST_LENGTH
(
pScan
->
pScanCols
));
CHECK_ALLOC
(
pScan
->
node
.
pTargets
,
(
SLogicNode
*
)
pScan
);
return
(
SLogicNode
*
)
pScan
;
}
static
SLogicNode
*
createSubqueryLogicNode
(
SSelectStmt
*
pSelect
,
STempTableNode
*
pTable
)
{
return
createQueryLogicNode
(
pTable
->
pSubquery
);
static
SLogicNode
*
createQueryLogicNode
(
SPlanContext
*
pCxt
,
SNode
*
pStmt
);
static
SLogicNode
*
createSubqueryLogicNode
(
SPlanContext
*
pCxt
,
SSelectStmt
*
pSelect
,
STempTableNode
*
pTable
)
{
return
createQueryLogicNode
(
pCxt
,
pTable
->
pSubquery
);
}
static
SLogicNode
*
createLogicNodeByTable
(
SSelectStmt
*
pSelect
,
SNode
*
pTable
)
{
static
SLogicNode
*
createLogicNodeByTable
(
S
PlanContext
*
pCxt
,
S
SelectStmt
*
pSelect
,
SNode
*
pTable
)
{
switch
(
nodeType
(
pTable
))
{
case
QUERY_NODE_REAL_TABLE
:
return
createScanLogicNode
(
pSelect
,
(
SRealTableNode
*
)
pTable
);
return
createScanLogicNode
(
p
Cxt
,
p
Select
,
(
SRealTableNode
*
)
pTable
);
case
QUERY_NODE_TEMP_TABLE
:
return
createSubqueryLogicNode
(
pSelect
,
(
STempTableNode
*
)
pTable
);
return
createSubqueryLogicNode
(
p
Cxt
,
p
Select
,
(
STempTableNode
*
)
pTable
);
case
QUERY_NODE_JOIN_TABLE
:
default:
break
;
...
...
@@ -160,45 +161,86 @@ static SLogicNode* createLogicNodeByTable(SSelectStmt* pSelect, SNode* pTable) {
return
NULL
;
}
static
SLogicNode
*
createFilterLogicNode
(
SNode
*
pWhere
)
{
static
SLogicNode
*
createFilterLogicNode
(
S
PlanContext
*
pCxt
,
SSelectStmt
*
pSelect
,
S
Node
*
pWhere
)
{
if
(
NULL
==
pWhere
)
{
return
NULL
;
}
SFilterLogicNode
*
pFilter
=
(
SFilterLogicNode
*
)
nodesMakeNode
(
QUERY_NODE_LOGIC_PLAN_FILTER
);
CHECK_ALLOC
(
pFilter
,
NULL
);
pFilter
->
node
.
id
=
pCxt
->
planNodeId
++
;
// set filter conditions
pFilter
->
node
.
pConditions
=
nodesCloneNode
(
pWhere
);
CHECK_ALLOC
(
pFilter
->
node
.
pConditions
,
(
SLogicNode
*
)
pFilter
);
// set the output and rewrite the expression in subsequent clauses with the output
SNodeList
*
pCols
=
NULL
;
CHECK_CODE
(
nodesCollectColumns
(
pSelect
,
SQL_CLAUSE_WHERE
,
0
,
false
,
&
pCols
),
(
SLogicNode
*
)
pFilter
);
pFilter
->
node
.
pTargets
=
nodesCloneList
(
pCols
);
CHECK_ALLOC
(
pFilter
->
node
.
pTargets
,
(
SLogicNode
*
)
pFilter
);
CHECK_CODE
(
rewriteExpr
(
pFilter
->
node
.
id
,
pFilter
->
node
.
pTargets
,
pSelect
,
SQL_CLAUSE_WHERE
),
(
SLogicNode
*
)
pFilter
);
return
(
SLogicNode
*
)
pFilter
;
}
static
SLogicNode
*
createAggLogicNode
(
SSelectStmt
*
pSelect
,
SNodeList
*
pGroupByList
,
SNode
*
pHaving
)
{
SNodeList
*
pAggFuncs
=
collectAggFuncs
(
pSelect
);
static
SLogicNode
*
createAggLogicNode
(
SPlanContext
*
pCxt
,
SSelectStmt
*
pSelect
,
SNodeList
*
pGroupByList
,
SNode
*
pHaving
)
{
SNodeList
*
pAggFuncs
=
NULL
;
CHECK_CODE
(
nodesCollectFuncs
(
pSelect
,
fmIsAggFunc
,
&
pAggFuncs
),
NULL
);
if
(
NULL
==
pAggFuncs
&&
NULL
==
pGroupByList
)
{
return
NULL
;
}
SAggLogicNode
*
pAgg
=
(
SAggLogicNode
*
)
nodesMakeNode
(
QUERY_NODE_LOGIC_PLAN_AGG
);
CHECK_ALLOC
(
pAgg
,
NULL
);
pAgg
->
node
.
id
=
pCxt
->
planNodeId
++
;
// set grouyp keys, agg funcs and having conditions
pAgg
->
pGroupKeys
=
nodesCloneList
(
pGroupByList
);
CHECK_ALLOC
(
pAgg
->
pGroupKeys
,
(
SLogicNode
*
)
pAgg
);
pAgg
->
pAggFuncs
=
nodesCloneList
(
pAggFuncs
);
CHECK_ALLOC
(
pAgg
->
pAggFuncs
,
(
SLogicNode
*
)
pAgg
);
pAgg
->
node
.
pConditions
=
nodesCloneNode
(
pHaving
);
CHECK_ALLOC
(
pAgg
->
node
.
pConditions
,
(
SLogicNode
*
)
pAgg
);
// set the output and rewrite the expression in subsequent clauses with the output
SNodeList
*
pCols
=
NULL
;
CHECK_CODE
(
nodesCollectColumns
(
pSelect
,
SQL_CLAUSE_HAVING
,
0
,
false
,
&
pCols
),
(
SLogicNode
*
)
pAgg
);
pAgg
->
node
.
pTargets
=
nodesCloneList
(
pCols
);
CHECK_ALLOC
(
pAgg
->
node
.
pTargets
,
(
SLogicNode
*
)
pAgg
);
CHECK_CODE
(
rewriteExpr
(
pAgg
->
node
.
id
,
pAgg
->
node
.
pTargets
,
pSelect
,
SQL_CLAUSE_HAVING
),
(
SLogicNode
*
)
pAgg
);
return
(
SLogicNode
*
)
pAgg
;
}
static
SLogicNode
*
createSelectLogicNode
(
SSelectStmt
*
pSelect
)
{
SLogicNode
*
pRoot
=
createLogicNodeByTable
(
pSelect
,
pSelect
->
pFromTable
);
pRoot
=
pushLogicNode
(
pRoot
,
createFilterLogicNode
(
pSelect
->
pWhere
));
pRoot
=
pushLogicNode
(
pRoot
,
createAggLogicNode
(
pSelect
,
pSelect
->
pGroupByList
,
pSelect
->
pHaving
));
// pRoot = pushLogicNode(pRoot, createProjectLogicNode(pSelect, pSelect->pProjectionList));
static
SLogicNode
*
createSelectLogicNode
(
SPlanContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
SLogicNode
*
pRoot
=
createLogicNodeByTable
(
pCxt
,
pSelect
,
pSelect
->
pFromTable
);
if
(
TSDB_CODE_SUCCESS
==
pCxt
->
errCode
)
{
pRoot
=
pushLogicNode
(
pCxt
,
pRoot
,
createFilterLogicNode
(
pCxt
,
pSelect
,
pSelect
->
pWhere
));
}
if
(
TSDB_CODE_SUCCESS
==
pCxt
->
errCode
)
{
pRoot
=
pushLogicNode
(
pCxt
,
pRoot
,
createAggLogicNode
(
pCxt
,
pSelect
,
pSelect
->
pGroupByList
,
pSelect
->
pHaving
));
}
// pRoot = pushLogicNode(pCxt, pRoot, createProjectLogicNode(pSelect, pSelect->pProjectionList));
return
pRoot
;
}
static
SLogicNode
*
createQueryLogicNode
(
SNode
*
pStmt
)
{
static
SLogicNode
*
createQueryLogicNode
(
S
PlanContext
*
pCxt
,
S
Node
*
pStmt
)
{
switch
(
nodeType
(
pStmt
))
{
case
QUERY_NODE_SELECT_STMT
:
return
createSelectLogicNode
((
SSelectStmt
*
)
pStmt
);
return
createSelectLogicNode
(
pCxt
,
(
SSelectStmt
*
)
pStmt
);
default:
break
;
}
}
int32_t
createLogicPlan
(
SNode
*
pNode
,
SLogicNode
**
pLogicNode
)
{
*
pLogicNode
=
createQueryLogicNode
(
pNode
);
SPlanContext
cxt
=
{
.
errCode
=
TSDB_CODE_SUCCESS
,
.
planNodeId
=
0
};
SLogicNode
*
pRoot
=
createQueryLogicNode
(
&
cxt
,
pNode
);
if
(
TSDB_CODE_SUCCESS
!=
cxt
.
errCode
)
{
nodesDestroyNode
((
SNode
*
)
pRoot
);
return
cxt
.
errCode
;
}
*
pLogicNode
=
pRoot
;
return
TSDB_CODE_SUCCESS
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录