Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
9c68bde6
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看板
提交
9c68bde6
编写于
6月 26, 2022
作者:
X
Xiaoyu Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: tail function rewrite to statement
上级
ab95a49f
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
94 addition
and
220 deletion
+94
-220
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+0
-108
source/libs/planner/src/planOptimizer.c
source/libs/planner/src/planOptimizer.c
+94
-112
未找到文件。
source/libs/parser/src/parTranslater.c
浏览文件 @
9c68bde6
...
...
@@ -2456,111 +2456,6 @@ static int32_t rewriteUniqueStmt(STranslateContext* pCxt, SSelectStmt* pSelect)
return
cxt
.
pTranslateCxt
->
errCode
;
}
typedef
struct
SRwriteTailCxt
{
STranslateContext
*
pTranslateCxt
;
int64_t
limit
;
int64_t
offset
;
}
SRwriteTailCxt
;
static
EDealRes
rewriteTailFunc
(
SNode
**
pNode
,
void
*
pContext
)
{
SRwriteTailCxt
*
pCxt
=
pContext
;
if
(
QUERY_NODE_FUNCTION
==
nodeType
(
*
pNode
))
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
*
pNode
;
if
(
FUNCTION_TYPE_TAIL
==
pFunc
->
funcType
)
{
pCxt
->
limit
=
((
SValueNode
*
)
nodesListGetNode
(
pFunc
->
pParameterList
,
1
))
->
datum
.
i
;
if
(
3
==
LIST_LENGTH
(
pFunc
->
pParameterList
))
{
pCxt
->
offset
=
((
SValueNode
*
)
nodesListGetNode
(
pFunc
->
pParameterList
,
2
))
->
datum
.
i
;
}
SNode
*
pExpr
=
nodesListGetNode
(
pFunc
->
pParameterList
,
0
);
strcpy
(((
SExprNode
*
)
pExpr
)
->
aliasName
,
((
SExprNode
*
)
*
pNode
)
->
aliasName
);
NODES_CLEAR_LIST
(
pFunc
->
pParameterList
);
nodesDestroyNode
(
*
pNode
);
*
pNode
=
pExpr
;
return
DEAL_RES_IGNORE_CHILD
;
}
}
return
DEAL_RES_CONTINUE
;
}
static
int32_t
createLimieNode
(
SRwriteTailCxt
*
pCxt
,
SLimitNode
**
pOutput
)
{
*
pOutput
=
(
SLimitNode
*
)
nodesMakeNode
(
QUERY_NODE_LIMIT
);
if
(
NULL
==
*
pOutput
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
(
*
pOutput
)
->
limit
=
pCxt
->
limit
;
(
*
pOutput
)
->
offset
=
pCxt
->
offset
;
return
TSDB_CODE_SUCCESS
;
}
static
SNode
*
createOrderByExpr
(
STranslateContext
*
pCxt
)
{
SOrderByExprNode
*
pOrder
=
(
SOrderByExprNode
*
)
nodesMakeNode
(
QUERY_NODE_ORDER_BY_EXPR
);
if
(
NULL
==
pOrder
)
{
return
NULL
;
}
pCxt
->
errCode
=
createPrimaryKeyCol
(
pCxt
,
&
pOrder
->
pExpr
);
if
(
TSDB_CODE_SUCCESS
!=
pCxt
->
errCode
)
{
nodesDestroyNode
((
SNode
*
)
pOrder
);
return
NULL
;
}
pOrder
->
order
=
ORDER_DESC
;
pOrder
->
nullOrder
=
NULL_ORDER_FIRST
;
return
(
SNode
*
)
pOrder
;
}
static
int32_t
rewriteTailStmtInplace
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
SRwriteTailCxt
cxt
=
{.
pTranslateCxt
=
pCxt
,
.
limit
=
-
1
,
.
offset
=
-
1
};
nodesRewriteExprs
(
pSelect
->
pProjectionList
,
rewriteTailFunc
,
&
cxt
);
int32_t
code
=
nodesListMakeStrictAppend
(
&
pSelect
->
pOrderByList
,
createOrderByExpr
(
pCxt
));
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
createLimieNode
(
&
cxt
,
&
pSelect
->
pLimit
);
}
pSelect
->
hasIndefiniteRowsFunc
=
false
;
pSelect
->
groupSort
=
(
NULL
!=
pSelect
->
pPartitionByList
);
return
code
;
}
static
int32_t
rewriteTailStmtSubquery
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
SSelectStmt
*
pSubquery
=
(
SSelectStmt
*
)
nodesMakeNode
(
QUERY_NODE_SELECT_STMT
);
if
(
NULL
==
pSubquery
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
TSWAP
(
pSubquery
->
pProjectionList
,
pSelect
->
pProjectionList
);
return
TSDB_CODE_PAR_INTERNAL_ERROR
;
}
/* case 1:
* in: select tail(expr, k, f) from t where_clause
* out: select expr from t where_clause order by _rowts desc limit k offset f
*
* case 2:
* in: select tail(expr, k, f) from t where_clause partition_by_clause
* out: select expr from t where_clause partition_by_clause sort by _rowts desc limit k offset f
*
* case 3:
* in: select tail(expr, k, f) from t where_clause order_by_clause limit_clause
* out: select expr from (
* select expr from t where_clause order by _rowts desc limit k offset f
* ) order_by_clause limit_clause
*
* case 4:
* in: select tail(expr, k, f) from t where_clause partition_by_clause limit_clause
* out: select expr from (
* select expr, part_key_list from t where_clause partition_by_clause sort by _rowts desc limit k offset f
* ) partition_by_clause limit_clause
*/
static
int32_t
rewriteTailStmt
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
if
(
!
pSelect
->
hasTailFunc
)
{
return
TSDB_CODE_SUCCESS
;
}
if
(
NULL
==
pSelect
->
pOrderByList
&&
NULL
==
pSelect
->
pLimit
&&
NULL
==
pSelect
->
pSlimit
)
{
return
rewriteTailStmtInplace
(
pCxt
,
pSelect
);
}
else
{
return
rewriteTailStmtSubquery
(
pCxt
,
pSelect
);
}
}
typedef
struct
SReplaceOrderByAliasCxt
{
STranslateContext
*
pTranslateCxt
;
SNodeList
*
pProjectionList
;
...
...
@@ -2637,9 +2532,6 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
rewriteUniqueStmt
(
pCxt
,
pSelect
);
}
// if (TSDB_CODE_SUCCESS == code) {
// code = rewriteTailStmt(pCxt, pSelect);
// }
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
rewriteTimelineFunc
(
pCxt
,
pSelect
);
}
...
...
source/libs/planner/src/planOptimizer.c
浏览文件 @
9c68bde6
...
...
@@ -233,7 +233,7 @@ static void setScanWindowInfo(SScanLogicNode* pScan) {
}
}
static
int32_t
osd
Optimize
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
)
{
static
int32_t
pickScanPath
Optimize
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
)
{
SOsdInfo
info
=
{
0
};
int32_t
code
=
osdMatch
(
pCxt
,
pLogicSubplan
->
pNode
,
&
info
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
info
.
pScan
)
{
...
...
@@ -249,7 +249,7 @@ static int32_t osdOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan)
return
code
;
}
static
int32_t
cpd
MergeCond
(
SNode
**
pDst
,
SNode
**
pSrc
)
{
static
int32_t
pdcOpt
MergeCond
(
SNode
**
pDst
,
SNode
**
pSrc
)
{
SLogicConditionNode
*
pLogicCond
=
(
SLogicConditionNode
*
)
nodesMakeNode
(
QUERY_NODE_LOGIC_CONDITION
);
if
(
NULL
==
pLogicCond
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
...
...
@@ -270,7 +270,7 @@ static int32_t cpdMergeCond(SNode** pDst, SNode** pSrc) {
return
code
;
}
static
int32_t
cpdCondAppe
nd
(
SNode
**
pCond
,
SNode
**
pAdditionalCond
)
{
static
int32_t
pdcOptAppendCo
nd
(
SNode
**
pCond
,
SNode
**
pAdditionalCond
)
{
if
(
NULL
==
*
pCond
)
{
TSWAP
(
*
pCond
,
*
pAdditionalCond
);
return
TSDB_CODE_SUCCESS
;
...
...
@@ -283,16 +283,16 @@ static int32_t cpdCondAppend(SNode** pCond, SNode** pAdditionalCond) {
*
pAdditionalCond
=
NULL
;
}
}
else
{
code
=
cpd
MergeCond
(
pCond
,
pAdditionalCond
);
code
=
pdcOpt
MergeCond
(
pCond
,
pAdditionalCond
);
}
return
code
;
}
static
int32_t
cpd
CalcTimeRange
(
SOptimizeContext
*
pCxt
,
SScanLogicNode
*
pScan
,
SNode
**
pPrimaryKeyCond
,
SNode
**
pOtherCond
)
{
static
int32_t
pdcOpt
CalcTimeRange
(
SOptimizeContext
*
pCxt
,
SScanLogicNode
*
pScan
,
SNode
**
pPrimaryKeyCond
,
SNode
**
pOtherCond
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
(
pCxt
->
pPlanCxt
->
topicQuery
||
pCxt
->
pPlanCxt
->
streamQuery
)
{
code
=
cpdCondAppe
nd
(
pOtherCond
,
pPrimaryKeyCond
);
code
=
pdcOptAppendCo
nd
(
pOtherCond
,
pPrimaryKeyCond
);
}
else
{
bool
isStrict
=
false
;
code
=
filterGetTimeRange
(
*
pPrimaryKeyCond
,
&
pScan
->
scanRange
,
&
isStrict
);
...
...
@@ -300,7 +300,7 @@ static int32_t cpdCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNode* pScan, S
if
(
isStrict
)
{
nodesDestroyNode
(
*
pPrimaryKeyCond
);
}
else
{
code
=
cpdCondAppe
nd
(
pOtherCond
,
pPrimaryKeyCond
);
code
=
pdcOptAppendCo
nd
(
pOtherCond
,
pPrimaryKeyCond
);
}
*
pPrimaryKeyCond
=
NULL
;
}
...
...
@@ -308,7 +308,7 @@ static int32_t cpdCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNode* pScan, S
return
code
;
}
static
int32_t
cpdOptimizeScanConditio
n
(
SOptimizeContext
*
pCxt
,
SScanLogicNode
*
pScan
)
{
static
int32_t
pdcOptDealSca
n
(
SOptimizeContext
*
pCxt
,
SScanLogicNode
*
pScan
)
{
if
(
NULL
==
pScan
->
node
.
pConditions
||
OPTIMIZE_FLAG_TEST_MASK
(
pScan
->
node
.
optimizedFlag
,
OPTIMIZE_FLAG_CPD
)
||
TSDB_SYSTEM_TABLE
==
pScan
->
tableType
)
{
return
TSDB_CODE_SUCCESS
;
...
...
@@ -319,7 +319,7 @@ static int32_t cpdOptimizeScanCondition(SOptimizeContext* pCxt, SScanLogicNode*
int32_t
code
=
nodesPartitionCond
(
&
pScan
->
node
.
pConditions
,
&
pPrimaryKeyCond
,
&
pScan
->
pTagIndexCond
,
&
pScan
->
pTagCond
,
&
pOtherCond
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pPrimaryKeyCond
)
{
code
=
cpd
CalcTimeRange
(
pCxt
,
pScan
,
&
pPrimaryKeyCond
,
&
pOtherCond
);
code
=
pdcOpt
CalcTimeRange
(
pCxt
,
pScan
,
&
pPrimaryKeyCond
,
&
pOtherCond
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
pScan
->
node
.
pConditions
=
pOtherCond
;
...
...
@@ -336,7 +336,7 @@ static int32_t cpdOptimizeScanCondition(SOptimizeContext* pCxt, SScanLogicNode*
return
code
;
}
static
bool
cpd
BelongThisTable
(
SNode
*
pCondCol
,
SNodeList
*
pTableCols
)
{
static
bool
pdcOpt
BelongThisTable
(
SNode
*
pCondCol
,
SNodeList
*
pTableCols
)
{
SNode
*
pTableCol
=
NULL
;
FOREACH
(
pTableCol
,
pTableCols
)
{
if
(
nodesEqualNode
(
pCondCol
,
pTableCol
))
{
...
...
@@ -346,12 +346,12 @@ static bool cpdBelongThisTable(SNode* pCondCol, SNodeList* pTableCols) {
return
false
;
}
static
EDealRes
cpdIsMultiTableCondImpl
(
SNode
*
pNode
,
void
*
pContext
)
{
static
EDealRes
pdcOptIsCrossTableCond
(
SNode
*
pNode
,
void
*
pContext
)
{
SCpdIsMultiTableCondCxt
*
pCxt
=
pContext
;
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pNode
))
{
if
(
cpd
BelongThisTable
(
pNode
,
pCxt
->
pLeftCols
))
{
if
(
pdcOpt
BelongThisTable
(
pNode
,
pCxt
->
pLeftCols
))
{
pCxt
->
havaLeftCol
=
true
;
}
else
if
(
cpd
BelongThisTable
(
pNode
,
pCxt
->
pRightCols
))
{
}
else
if
(
pdcOpt
BelongThisTable
(
pNode
,
pCxt
->
pRightCols
))
{
pCxt
->
haveRightCol
=
true
;
}
return
pCxt
->
havaLeftCol
&&
pCxt
->
haveRightCol
?
DEAL_RES_END
:
DEAL_RES_CONTINUE
;
...
...
@@ -359,10 +359,10 @@ static EDealRes cpdIsMultiTableCondImpl(SNode* pNode, void* pContext) {
return
DEAL_RES_CONTINUE
;
}
static
ECondAction
cpd
CondAction
(
EJoinType
joinType
,
SNodeList
*
pLeftCols
,
SNodeList
*
pRightCols
,
SNode
*
pNode
)
{
static
ECondAction
pdcOptGet
CondAction
(
EJoinType
joinType
,
SNodeList
*
pLeftCols
,
SNodeList
*
pRightCols
,
SNode
*
pNode
)
{
SCpdIsMultiTableCondCxt
cxt
=
{
.
pLeftCols
=
pLeftCols
,
.
pRightCols
=
pRightCols
,
.
havaLeftCol
=
false
,
.
haveRightCol
=
false
};
nodesWalkExpr
(
pNode
,
cpdIsMultiTableCondImpl
,
&
cxt
);
nodesWalkExpr
(
pNode
,
pdcOptIsCrossTableCond
,
&
cxt
);
return
(
JOIN_TYPE_INNER
!=
joinType
?
COND_ACTION_STAY
:
(
cxt
.
havaLeftCol
&&
cxt
.
haveRightCol
...
...
@@ -370,8 +370,8 @@ static ECondAction cpdCondAction(EJoinType joinType, SNodeList* pLeftCols, SNode
:
(
cxt
.
havaLeftCol
?
COND_ACTION_PUSH_LEFT_CHILD
:
COND_ACTION_PUSH_RIGHT_CHILD
)));
}
static
int32_t
cpd
PartitionLogicCond
(
SJoinLogicNode
*
pJoin
,
SNode
**
pOnCond
,
SNode
**
pLeftChildCond
,
SNode
**
pRightChildCond
)
{
static
int32_t
pdcOpt
PartitionLogicCond
(
SJoinLogicNode
*
pJoin
,
SNode
**
pOnCond
,
SNode
**
pLeftChildCond
,
SNode
**
pRightChildCond
)
{
SLogicConditionNode
*
pLogicCond
=
(
SLogicConditionNode
*
)
pJoin
->
node
.
pConditions
;
if
(
LOGIC_COND_TYPE_AND
!=
pLogicCond
->
condType
)
{
return
TSDB_CODE_SUCCESS
;
...
...
@@ -387,7 +387,7 @@ static int32_t cpdPartitionLogicCond(SJoinLogicNode* pJoin, SNode** pOnCond, SNo
SNodeList
*
pRemainConds
=
NULL
;
SNode
*
pCond
=
NULL
;
FOREACH
(
pCond
,
pLogicCond
->
pParameterList
)
{
ECondAction
condAction
=
cpd
CondAction
(
pJoin
->
joinType
,
pLeftCols
,
pRightCols
,
pCond
);
ECondAction
condAction
=
pdcOptGet
CondAction
(
pJoin
->
joinType
,
pLeftCols
,
pRightCols
,
pCond
);
if
(
COND_ACTION_PUSH_JOIN
==
condAction
)
{
code
=
nodesListMakeAppend
(
&
pOnConds
,
nodesCloneNode
(
pCond
));
}
else
if
(
COND_ACTION_PUSH_LEFT_CHILD
==
condAction
)
{
...
...
@@ -439,11 +439,11 @@ static int32_t cpdPartitionLogicCond(SJoinLogicNode* pJoin, SNode** pOnCond, SNo
return
code
;
}
static
int32_t
cpd
PartitionOpCond
(
SJoinLogicNode
*
pJoin
,
SNode
**
pOnCond
,
SNode
**
pLeftChildCond
,
SNode
**
pRightChildCond
)
{
static
int32_t
pdcOpt
PartitionOpCond
(
SJoinLogicNode
*
pJoin
,
SNode
**
pOnCond
,
SNode
**
pLeftChildCond
,
SNode
**
pRightChildCond
)
{
SNodeList
*
pLeftCols
=
((
SLogicNode
*
)
nodesListGetNode
(
pJoin
->
node
.
pChildren
,
0
))
->
pTargets
;
SNodeList
*
pRightCols
=
((
SLogicNode
*
)
nodesListGetNode
(
pJoin
->
node
.
pChildren
,
1
))
->
pTargets
;
ECondAction
condAction
=
cpd
CondAction
(
pJoin
->
joinType
,
pLeftCols
,
pRightCols
,
pJoin
->
node
.
pConditions
);
ECondAction
condAction
=
pdcOptGet
CondAction
(
pJoin
->
joinType
,
pLeftCols
,
pRightCols
,
pJoin
->
node
.
pConditions
);
if
(
COND_ACTION_STAY
==
condAction
)
{
return
TSDB_CODE_SUCCESS
;
}
else
if
(
COND_ACTION_PUSH_JOIN
==
condAction
)
{
...
...
@@ -457,35 +457,35 @@ static int32_t cpdPartitionOpCond(SJoinLogicNode* pJoin, SNode** pOnCond, SNode*
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
cpd
PartitionCond
(
SJoinLogicNode
*
pJoin
,
SNode
**
pOnCond
,
SNode
**
pLeftChildCond
,
SNode
**
pRightChildCond
)
{
static
int32_t
pdcOpt
PartitionCond
(
SJoinLogicNode
*
pJoin
,
SNode
**
pOnCond
,
SNode
**
pLeftChildCond
,
SNode
**
pRightChildCond
)
{
if
(
QUERY_NODE_LOGIC_CONDITION
==
nodeType
(
pJoin
->
node
.
pConditions
))
{
return
cpd
PartitionLogicCond
(
pJoin
,
pOnCond
,
pLeftChildCond
,
pRightChildCond
);
return
pdcOpt
PartitionLogicCond
(
pJoin
,
pOnCond
,
pLeftChildCond
,
pRightChildCond
);
}
else
{
return
cpd
PartitionOpCond
(
pJoin
,
pOnCond
,
pLeftChildCond
,
pRightChildCond
);
return
pdcOpt
PartitionOpCond
(
pJoin
,
pOnCond
,
pLeftChildCond
,
pRightChildCond
);
}
}
static
int32_t
cpd
PushCondToOnCond
(
SOptimizeContext
*
pCxt
,
SJoinLogicNode
*
pJoin
,
SNode
**
pCond
)
{
return
cpdCondAppe
nd
(
&
pJoin
->
pOnConditions
,
pCond
);
static
int32_t
pdcOpt
PushCondToOnCond
(
SOptimizeContext
*
pCxt
,
SJoinLogicNode
*
pJoin
,
SNode
**
pCond
)
{
return
pdcOptAppendCo
nd
(
&
pJoin
->
pOnConditions
,
pCond
);
}
static
int32_t
cpd
PushCondToScan
(
SOptimizeContext
*
pCxt
,
SScanLogicNode
*
pScan
,
SNode
**
pCond
)
{
return
cpdCondAppe
nd
(
&
pScan
->
node
.
pConditions
,
pCond
);
static
int32_t
pdcOpt
PushCondToScan
(
SOptimizeContext
*
pCxt
,
SScanLogicNode
*
pScan
,
SNode
**
pCond
)
{
return
pdcOptAppendCo
nd
(
&
pScan
->
node
.
pConditions
,
pCond
);
}
static
int32_t
cpd
PushCondToChild
(
SOptimizeContext
*
pCxt
,
SLogicNode
*
pChild
,
SNode
**
pCond
)
{
static
int32_t
pdcOpt
PushCondToChild
(
SOptimizeContext
*
pCxt
,
SLogicNode
*
pChild
,
SNode
**
pCond
)
{
switch
(
nodeType
(
pChild
))
{
case
QUERY_NODE_LOGIC_PLAN_SCAN
:
return
cpd
PushCondToScan
(
pCxt
,
(
SScanLogicNode
*
)
pChild
,
pCond
);
return
pdcOpt
PushCondToScan
(
pCxt
,
(
SScanLogicNode
*
)
pChild
,
pCond
);
default:
break
;
}
planError
(
"
cpd
PushCondToChild failed, invalid logic plan node %s"
,
nodesNodeName
(
nodeType
(
pChild
)));
planError
(
"
pdcOpt
PushCondToChild failed, invalid logic plan node %s"
,
nodesNodeName
(
nodeType
(
pChild
)));
return
TSDB_CODE_PLAN_INTERNAL_ERROR
;
}
static
bool
cpd
IsPrimaryKey
(
SNode
*
pNode
,
SNodeList
*
pTableCols
)
{
static
bool
pdcOpt
IsPrimaryKey
(
SNode
*
pNode
,
SNodeList
*
pTableCols
)
{
if
(
QUERY_NODE_COLUMN
!=
nodeType
(
pNode
))
{
return
false
;
}
...
...
@@ -493,10 +493,10 @@ static bool cpdIsPrimaryKey(SNode* pNode, SNodeList* pTableCols) {
if
(
PRIMARYKEY_TIMESTAMP_COL_ID
!=
pCol
->
colId
)
{
return
false
;
}
return
cpd
BelongThisTable
(
pNode
,
pTableCols
);
return
pdcOpt
BelongThisTable
(
pNode
,
pTableCols
);
}
static
bool
cpd
IsPrimaryKeyEqualCond
(
SJoinLogicNode
*
pJoin
,
SNode
*
pCond
)
{
static
bool
pdcOpt
IsPrimaryKeyEqualCond
(
SJoinLogicNode
*
pJoin
,
SNode
*
pCond
)
{
if
(
QUERY_NODE_OPERATOR
!=
nodeType
(
pCond
))
{
return
false
;
}
...
...
@@ -508,15 +508,15 @@ static bool cpdIsPrimaryKeyEqualCond(SJoinLogicNode* pJoin, SNode* pCond) {
SNodeList
*
pLeftCols
=
((
SLogicNode
*
)
nodesListGetNode
(
pJoin
->
node
.
pChildren
,
0
))
->
pTargets
;
SNodeList
*
pRightCols
=
((
SLogicNode
*
)
nodesListGetNode
(
pJoin
->
node
.
pChildren
,
1
))
->
pTargets
;
if
(
cpd
IsPrimaryKey
(
pOper
->
pLeft
,
pLeftCols
))
{
return
cpd
IsPrimaryKey
(
pOper
->
pRight
,
pRightCols
);
}
else
if
(
cpd
IsPrimaryKey
(
pOper
->
pLeft
,
pRightCols
))
{
return
cpd
IsPrimaryKey
(
pOper
->
pRight
,
pLeftCols
);
if
(
pdcOpt
IsPrimaryKey
(
pOper
->
pLeft
,
pLeftCols
))
{
return
pdcOpt
IsPrimaryKey
(
pOper
->
pRight
,
pRightCols
);
}
else
if
(
pdcOpt
IsPrimaryKey
(
pOper
->
pLeft
,
pRightCols
))
{
return
pdcOpt
IsPrimaryKey
(
pOper
->
pRight
,
pLeftCols
);
}
return
false
;
}
static
bool
cpdContainPrimary
KeyEqualCond
(
SJoinLogicNode
*
pJoin
,
SNode
*
pCond
)
{
static
bool
pdcOptContainPri
KeyEqualCond
(
SJoinLogicNode
*
pJoin
,
SNode
*
pCond
)
{
if
(
QUERY_NODE_LOGIC_CONDITION
==
nodeType
(
pCond
))
{
SLogicConditionNode
*
pLogicCond
=
(
SLogicConditionNode
*
)
pCond
;
if
(
LOGIC_COND_TYPE_AND
!=
pLogicCond
->
condType
)
{
...
...
@@ -525,54 +525,54 @@ static bool cpdContainPrimaryKeyEqualCond(SJoinLogicNode* pJoin, SNode* pCond) {
bool
hasPrimaryKeyEqualCond
=
false
;
SNode
*
pCond
=
NULL
;
FOREACH
(
pCond
,
pLogicCond
->
pParameterList
)
{
if
(
cpdContainPrimary
KeyEqualCond
(
pJoin
,
pCond
))
{
if
(
pdcOptContainPri
KeyEqualCond
(
pJoin
,
pCond
))
{
hasPrimaryKeyEqualCond
=
true
;
break
;
}
}
return
hasPrimaryKeyEqualCond
;
}
else
{
return
cpd
IsPrimaryKeyEqualCond
(
pJoin
,
pCond
);
return
pdcOpt
IsPrimaryKeyEqualCond
(
pJoin
,
pCond
);
}
}
static
int32_t
cpd
CheckJoinOnCond
(
SOptimizeContext
*
pCxt
,
SJoinLogicNode
*
pJoin
)
{
static
int32_t
pdcOpt
CheckJoinOnCond
(
SOptimizeContext
*
pCxt
,
SJoinLogicNode
*
pJoin
)
{
if
(
NULL
==
pJoin
->
pOnConditions
)
{
return
generateUsageErrMsg
(
pCxt
->
pPlanCxt
->
pMsg
,
pCxt
->
pPlanCxt
->
msgLen
,
TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN
);
}
if
(
!
cpdContainPrimary
KeyEqualCond
(
pJoin
,
pJoin
->
pOnConditions
))
{
if
(
!
pdcOptContainPri
KeyEqualCond
(
pJoin
,
pJoin
->
pOnConditions
))
{
return
generateUsageErrMsg
(
pCxt
->
pPlanCxt
->
pMsg
,
pCxt
->
pPlanCxt
->
msgLen
,
TSDB_CODE_PLAN_EXPECTED_TS_EQUAL
);
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
cpdPushJoinConditio
n
(
SOptimizeContext
*
pCxt
,
SJoinLogicNode
*
pJoin
)
{
static
int32_t
pdcOptDealJoi
n
(
SOptimizeContext
*
pCxt
,
SJoinLogicNode
*
pJoin
)
{
if
(
OPTIMIZE_FLAG_TEST_MASK
(
pJoin
->
node
.
optimizedFlag
,
OPTIMIZE_FLAG_CPD
))
{
return
TSDB_CODE_SUCCESS
;
}
if
(
NULL
==
pJoin
->
node
.
pConditions
)
{
return
cpd
CheckJoinOnCond
(
pCxt
,
pJoin
);
return
pdcOpt
CheckJoinOnCond
(
pCxt
,
pJoin
);
}
SNode
*
pOnCond
=
NULL
;
SNode
*
pLeftChildCond
=
NULL
;
SNode
*
pRightChildCond
=
NULL
;
int32_t
code
=
cpd
PartitionCond
(
pJoin
,
&
pOnCond
,
&
pLeftChildCond
,
&
pRightChildCond
);
int32_t
code
=
pdcOpt
PartitionCond
(
pJoin
,
&
pOnCond
,
&
pLeftChildCond
,
&
pRightChildCond
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pOnCond
)
{
code
=
cpd
PushCondToOnCond
(
pCxt
,
pJoin
,
&
pOnCond
);
code
=
pdcOpt
PushCondToOnCond
(
pCxt
,
pJoin
,
&
pOnCond
);
}
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pLeftChildCond
)
{
code
=
cpd
PushCondToChild
(
pCxt
,
(
SLogicNode
*
)
nodesListGetNode
(
pJoin
->
node
.
pChildren
,
0
),
&
pLeftChildCond
);
code
=
pdcOpt
PushCondToChild
(
pCxt
,
(
SLogicNode
*
)
nodesListGetNode
(
pJoin
->
node
.
pChildren
,
0
),
&
pLeftChildCond
);
}
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pRightChildCond
)
{
code
=
cpd
PushCondToChild
(
pCxt
,
(
SLogicNode
*
)
nodesListGetNode
(
pJoin
->
node
.
pChildren
,
1
),
&
pRightChildCond
);
code
=
pdcOpt
PushCondToChild
(
pCxt
,
(
SLogicNode
*
)
nodesListGetNode
(
pJoin
->
node
.
pChildren
,
1
),
&
pRightChildCond
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
OPTIMIZE_FLAG_SET_MASK
(
pJoin
->
node
.
optimizedFlag
,
OPTIMIZE_FLAG_CPD
);
pCxt
->
optimized
=
true
;
code
=
cpd
CheckJoinOnCond
(
pCxt
,
pJoin
);
code
=
pdcOpt
CheckJoinOnCond
(
pCxt
,
pJoin
);
}
else
{
nodesDestroyNode
(
pOnCond
);
nodesDestroyNode
(
pLeftChildCond
);
...
...
@@ -582,22 +582,22 @@ static int32_t cpdPushJoinCondition(SOptimizeContext* pCxt, SJoinLogicNode* pJoi
return
code
;
}
static
int32_t
cpdPushAggCondition
(
SOptimizeContext
*
pCxt
,
SAggLogicNode
*
pAgg
)
{
static
int32_t
pdcOptDealAgg
(
SOptimizeContext
*
pCxt
,
SAggLogicNode
*
pAgg
)
{
// todo
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
cpdPushCondition
(
SOptimizeContext
*
pCxt
,
SLogicNode
*
pLogicNode
)
{
static
int32_t
pushDownCondOptimizeImpl
(
SOptimizeContext
*
pCxt
,
SLogicNode
*
pLogicNode
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
switch
(
nodeType
(
pLogicNode
))
{
case
QUERY_NODE_LOGIC_PLAN_SCAN
:
code
=
cpdOptimizeScanConditio
n
(
pCxt
,
(
SScanLogicNode
*
)
pLogicNode
);
code
=
pdcOptDealSca
n
(
pCxt
,
(
SScanLogicNode
*
)
pLogicNode
);
break
;
case
QUERY_NODE_LOGIC_PLAN_JOIN
:
code
=
cpdPushJoinConditio
n
(
pCxt
,
(
SJoinLogicNode
*
)
pLogicNode
);
code
=
pdcOptDealJoi
n
(
pCxt
,
(
SJoinLogicNode
*
)
pLogicNode
);
break
;
case
QUERY_NODE_LOGIC_PLAN_AGG
:
code
=
cpdPushAggCondition
(
pCxt
,
(
SAggLogicNode
*
)
pLogicNode
);
code
=
pdcOptDealAgg
(
pCxt
,
(
SAggLogicNode
*
)
pLogicNode
);
break
;
default:
break
;
...
...
@@ -605,7 +605,7 @@ static int32_t cpdPushCondition(SOptimizeContext* pCxt, SLogicNode* pLogicNode)
if
(
TSDB_CODE_SUCCESS
==
code
)
{
SNode
*
pChild
=
NULL
;
FOREACH
(
pChild
,
pLogicNode
->
pChildren
)
{
code
=
cpdPushCondition
(
pCxt
,
(
SLogicNode
*
)
pChild
);
code
=
pushDownCondOptimizeImpl
(
pCxt
,
(
SLogicNode
*
)
pChild
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
break
;
}
...
...
@@ -614,11 +614,11 @@ static int32_t cpdPushCondition(SOptimizeContext* pCxt, SLogicNode* pLogicNode)
return
code
;
}
static
int32_t
cp
dOptimize
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
)
{
return
cpdPushCondition
(
pCxt
,
pLogicSubplan
->
pNode
);
static
int32_t
pushDownCon
dOptimize
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
)
{
return
pushDownCondOptimizeImpl
(
pCxt
,
pLogicSubplan
->
pNode
);
}
static
bool
opkIsPrimary
KeyOrderBy
(
SNodeList
*
pSortKeys
)
{
static
bool
sortPriKeyOptIsPri
KeyOrderBy
(
SNodeList
*
pSortKeys
)
{
if
(
1
!=
LIST_LENGTH
(
pSortKeys
))
{
return
false
;
}
...
...
@@ -626,17 +626,18 @@ static bool opkIsPrimaryKeyOrderBy(SNodeList* pSortKeys) {
return
(
QUERY_NODE_COLUMN
==
nodeType
(
pNode
)
?
(
PRIMARYKEY_TIMESTAMP_COL_ID
==
((
SColumnNode
*
)
pNode
)
->
colId
)
:
false
);
}
static
bool
opkSor
tMayBeOptimized
(
SLogicNode
*
pNode
)
{
static
bool
sortPriKeyOp
tMayBeOptimized
(
SLogicNode
*
pNode
)
{
if
(
QUERY_NODE_LOGIC_PLAN_SORT
!=
nodeType
(
pNode
))
{
return
false
;
}
if
(
OPTIMIZE_FLAG_TEST_MASK
(
pNode
->
optimizedFlag
,
OPTIMIZE_FLAG_OPK
))
{
return
false
;
SSortLogicNode
*
pSort
=
(
SSortLogicNode
*
)
pNode
;
if
(
pSort
->
groupSort
||
!
sortPriKeyOptIsPriKeyOrderBy
(
pSort
->
pSortKeys
)
||
1
!=
LIST_LENGTH
(
pSort
->
node
.
pChildren
))
{
return
TSDB_CODE_SUCCESS
;
}
return
true
;
}
static
int32_t
opk
GetScanNodesImpl
(
SLogicNode
*
pNode
,
bool
*
pNotOptimize
,
SNodeList
**
pScanNodes
)
{
static
int32_t
sortPriKeyOpt
GetScanNodesImpl
(
SLogicNode
*
pNode
,
bool
*
pNotOptimize
,
SNodeList
**
pScanNodes
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
switch
(
nodeType
(
pNode
))
{
...
...
@@ -646,9 +647,11 @@ static int32_t opkGetScanNodesImpl(SLogicNode* pNode, bool* pNotOptimize, SNodeL
}
break
;
case
QUERY_NODE_LOGIC_PLAN_JOIN
:
code
=
opkGetScanNodesImpl
((
SLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
0
),
pNotOptimize
,
pScanNodes
);
code
=
sortPriKeyOptGetScanNodesImpl
((
SLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
0
),
pNotOptimize
,
pScanNodes
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
opkGetScanNodesImpl
((
SLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
1
),
pNotOptimize
,
pScanNodes
);
code
=
sortPriKeyOptGetScanNodesImpl
((
SLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
1
),
pNotOptimize
,
pScanNodes
);
}
return
code
;
case
QUERY_NODE_LOGIC_PLAN_AGG
:
...
...
@@ -663,74 +666,55 @@ static int32_t opkGetScanNodesImpl(SLogicNode* pNode, bool* pNotOptimize, SNodeL
return
TSDB_CODE_SUCCESS
;
}
return
opk
GetScanNodesImpl
((
SLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
0
),
pNotOptimize
,
pScanNodes
);
return
sortPriKeyOpt
GetScanNodesImpl
((
SLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
0
),
pNotOptimize
,
pScanNodes
);
}
static
int32_t
opk
GetScanNodes
(
SLogicNode
*
pNode
,
SNodeList
**
pScanNodes
)
{
static
int32_t
sortPriKeyOpt
GetScanNodes
(
SLogicNode
*
pNode
,
SNodeList
**
pScanNodes
)
{
bool
notOptimize
=
false
;
int32_t
code
=
opk
GetScanNodesImpl
(
pNode
,
&
notOptimize
,
pScanNodes
);
int32_t
code
=
sortPriKeyOpt
GetScanNodesImpl
(
pNode
,
&
notOptimize
,
pScanNodes
);
if
(
TSDB_CODE_SUCCESS
!=
code
||
notOptimize
)
{
nodesClearList
(
*
pScanNodes
);
}
return
code
;
}
static
EOrder
opkGetPrimary
KeyOrder
(
SSortLogicNode
*
pSort
)
{
static
EOrder
sortPriKeyOptGetPri
KeyOrder
(
SSortLogicNode
*
pSort
)
{
return
((
SOrderByExprNode
*
)
nodesListGetNode
(
pSort
->
pSortKeys
,
0
))
->
order
;
}
static
SNode
*
opkRewriteDownNode
(
SSortLogicNode
*
pSort
)
{
SNode
*
pDownNode
=
nodesListGetNode
(
pSort
->
node
.
pChildren
,
0
);
// todo
NODES_CLEAR_LIST
(
pSort
->
node
.
pChildren
);
return
pDownNode
;
}
static
int32_t
opkDoOptimized
(
SOptimizeContext
*
pCxt
,
SSortLogicNode
*
pSort
,
SNodeList
*
pScanNodes
)
{
EOrder
order
=
opkGetPrimaryKeyOrder
(
pSort
);
static
int32_t
sortPriKeyOptApply
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
,
SSortLogicNode
*
pSort
,
SNodeList
*
pScanNodes
)
{
EOrder
order
=
sortPriKeyOptGetPriKeyOrder
(
pSort
);
if
(
ORDER_DESC
==
order
)
{
SNode
*
pScan
=
NULL
;
FOREACH
(
pScan
,
pScanNodes
)
{
TSWAP
(((
SScanLogicNode
*
)
pScan
)
->
scanSeq
[
0
],
((
SScanLogicNode
*
)
pScan
)
->
scanSeq
[
1
]);
}
}
if
(
NULL
==
pSort
->
node
.
pParent
)
{
// todo
return
TSDB_CODE_SUCCESS
;
}
SNode
*
pDownNode
=
opkRewriteDownNode
(
pSort
);
SNode
*
pNode
;
FOREACH
(
pNode
,
pSort
->
node
.
pParent
->
pChildren
)
{
if
(
nodesEqualNode
(
pNode
,
(
SNode
*
)
pSort
))
{
REPLACE_NODE
(
pDownNode
);
((
SLogicNode
*
)
pDownNode
)
->
pParent
=
pSort
->
node
.
pParent
;
break
;
}
int32_t
code
=
replaceLogicNode
(
pLogicSubplan
,
(
SLogicNode
*
)
pSort
,
(
SLogicNode
*
)
nodesListGetNode
(
pSort
->
node
.
pChildren
,
0
));
if
(
TSDB_CODE_SUCCESS
==
code
)
{
NODES_CLEAR_LIST
(
pSort
->
node
.
pChildren
);
nodesDestroyNode
((
SNode
*
)
pSort
);
}
nodesDestroyNode
((
SNode
*
)
pSort
);
return
TSDB_CODE_SUCCESS
;
return
code
;
}
static
int32_t
opkOptimizeImpl
(
SOptimizeContext
*
pCxt
,
SSortLogicNode
*
pSort
)
{
OPTIMIZE_FLAG_SET_MASK
(
pSort
->
node
.
optimizedFlag
,
OPTIMIZE_FLAG_OPK
);
if
(
!
opkIsPrimaryKeyOrderBy
(
pSort
->
pSortKeys
)
||
1
!=
LIST_LENGTH
(
pSort
->
node
.
pChildren
))
{
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
sortPrimaryKeyOptimizeImpl
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
,
SSortLogicNode
*
pSort
)
{
SNodeList
*
pScanNodes
=
NULL
;
int32_t
code
=
opk
GetScanNodes
((
SLogicNode
*
)
nodesListGetNode
(
pSort
->
node
.
pChildren
,
0
),
&
pScanNodes
);
int32_t
code
=
sortPriKeyOpt
GetScanNodes
((
SLogicNode
*
)
nodesListGetNode
(
pSort
->
node
.
pChildren
,
0
),
&
pScanNodes
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pScanNodes
)
{
code
=
opkDoOptimized
(
pCxt
,
pSort
,
pScanNodes
);
code
=
sortPriKeyOptApply
(
pCxt
,
pLogicSubplan
,
pSort
,
pScanNodes
);
}
nodesClearList
(
pScanNodes
);
return
code
;
}
static
int32_t
opk
Optimize
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
)
{
SSortLogicNode
*
pSort
=
(
SSortLogicNode
*
)
optFindPossibleNode
(
pLogicSubplan
->
pNode
,
opkSor
tMayBeOptimized
);
static
int32_t
sortPrimaryKey
Optimize
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
)
{
SSortLogicNode
*
pSort
=
(
SSortLogicNode
*
)
optFindPossibleNode
(
pLogicSubplan
->
pNode
,
sortPriKeyOp
tMayBeOptimized
);
if
(
NULL
==
pSort
)
{
return
TSDB_CODE_SUCCESS
;
}
return
opkOptimizeImpl
(
pCxt
,
pSort
);
return
sortPrimaryKeyOptimizeImpl
(
pCxt
,
pLogicSubplan
,
pSort
);
}
static
bool
smaOptMayBeOptimized
(
SLogicNode
*
pNode
)
{
...
...
@@ -1107,8 +1091,6 @@ static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
return
code
;
}
//=====================================================================================================================
// eliminate project optimization
static
bool
eliminateProjOptCheckProjColumnNames
(
SProjectLogicNode
*
pProjectNode
)
{
SHashObj
*
pProjColNameHash
=
taosHashInit
(
16
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BINARY
),
true
,
HASH_NO_LOCK
);
SNode
*
pProjection
;
...
...
@@ -1371,14 +1353,14 @@ static int32_t eliminateSetOpOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLo
// clang-format off
static
const
SOptimizeRule
optimizeRuleSet
[]
=
{
{.
pName
=
"
OptimizeScanData"
,
.
optimizeFunc
=
osd
Optimize
},
{.
pName
=
"
ConditionPushDown"
,
.
optimizeFunc
=
cp
dOptimize
},
{.
pName
=
"
OrderByPrimaryKey"
,
.
optimizeFunc
=
opk
Optimize
},
{.
pName
=
"Sma
Index"
,
.
optimizeFunc
=
smaOptimize
},
{.
pName
=
"
PickScanPath"
,
.
optimizeFunc
=
pickScanPath
Optimize
},
{.
pName
=
"
PushDownCondition"
,
.
optimizeFunc
=
pushDownCon
dOptimize
},
{.
pName
=
"
SortPrimaryKey"
,
.
optimizeFunc
=
sortPrimaryKey
Optimize
},
{.
pName
=
"Sma
"
,
.
optimizeFunc
=
smaOptimize
},
{.
pName
=
"PartitionTags"
,
.
optimizeFunc
=
partTagsOptimize
},
{.
pName
=
"EliminateProject"
,
.
optimizeFunc
=
eliminateProjOptimize
},
{.
pName
=
"EliminateSetOperator"
,
.
optimizeFunc
=
eliminateSetOpOptimize
},
{.
pName
=
"RewriteTail"
,
.
optimizeFunc
=
rewriteTailOptimize
}
//
{.pName = "RewriteTail", .optimizeFunc = rewriteTailOptimize}
};
// clang-format on
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录