Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
0fd30515
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看板
提交
0fd30515
编写于
12月 28, 2022
作者:
X
Xiaoyu Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
enh: when there is _wend and _wduration in the query, you can use tsma optimization
上级
b686e1fd
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
81 addition
and
35 deletion
+81
-35
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+74
-22
source/libs/planner/src/planOptimizer.c
source/libs/planner/src/planOptimizer.c
+7
-13
未找到文件。
source/libs/parser/src/parTranslater.c
浏览文件 @
0fd30515
...
...
@@ -4569,58 +4569,109 @@ typedef struct SSampleAstInfo {
SNode
*
pSliding
;
SNodeList
*
pPartitionByList
;
STableMeta
*
pRollupTableMeta
;
bool
createSmaIndex
;
}
SSampleAstInfo
;
static
int32_t
buildSampleAst
(
STranslateContext
*
pCxt
,
SSampleAstInfo
*
pInfo
,
char
**
pAst
,
int32_t
*
pLen
,
char
**
pExpr
,
int32_t
*
pExprLen
)
{
SSelectStmt
*
pSelect
=
(
SSelectStmt
*
)
nodesMakeNode
(
QUERY_NODE_SELECT_STMT
);
if
(
NULL
==
pSelect
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
sprintf
(
pSelect
->
stmtName
,
"%p"
,
pSelect
);
static
int32_t
buildTableForSampleAst
(
SSampleAstInfo
*
pInfo
,
SNode
**
pOutput
)
{
SRealTableNode
*
pTable
=
(
SRealTableNode
*
)
nodesMakeNode
(
QUERY_NODE_REAL_TABLE
);
if
(
NULL
==
pTable
)
{
nodesDestroyNode
((
SNode
*
)
pSelect
);
return
TSDB_CODE_OUT_OF_MEMORY
;
}
snprintf
(
pTable
->
table
.
dbName
,
sizeof
(
pTable
->
table
.
dbName
),
"%s"
,
pInfo
->
pDbName
);
snprintf
(
pTable
->
table
.
tableName
,
sizeof
(
pTable
->
table
.
tableName
),
"%s"
,
pInfo
->
pTableName
);
TSWAP
(
pTable
->
pMeta
,
pInfo
->
pRollupTableMeta
);
pSelect
->
pFromTable
=
(
SNode
*
)
pTable
;
*
pOutput
=
(
SNode
*
)
pTable
;
return
TSDB_CODE_SUCCESS
;
}
TSWAP
(
pSelect
->
pProjectionList
,
pInfo
->
pFuncs
);
static
int32_t
addWstartToSampleProjects
(
SNodeList
*
pProjectionList
)
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
nodesMakeNode
(
QUERY_NODE_FUNCTION
);
if
(
NULL
==
pSelect
->
pProjectionList
||
NULL
==
pFunc
)
{
nodesDestroyNode
((
SNode
*
)
pSelect
);
if
(
NULL
==
pFunc
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
strcpy
(
pFunc
->
functionName
,
"_wstart"
);
nodesListPushFront
(
pSelect
->
pProjectionList
,
(
SNode
*
)
pFunc
);
SNode
*
pProject
=
NULL
;
FOREACH
(
pProject
,
pSelect
->
pProjectionList
)
{
sprintf
(((
SExprNode
*
)
pProject
)
->
aliasName
,
"#%p"
,
pProject
);
}
return
nodesListPushFront
(
pProjectionList
,
(
SNode
*
)
pFunc
);
}
TSWAP
(
pSelect
->
pPartitionByList
,
pInfo
->
pPartitionByList
);
static
int32_t
addWendToSampleProjects
(
SNodeList
*
pProjectionList
)
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
nodesMakeNode
(
QUERY_NODE_FUNCTION
);
if
(
NULL
==
pFunc
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
strcpy
(
pFunc
->
functionName
,
"_wend"
);
return
nodesListAppend
(
pProjectionList
,
(
SNode
*
)
pFunc
);
}
static
int32_t
addWdurationToSampleProjects
(
SNodeList
*
pProjectionList
)
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
nodesMakeNode
(
QUERY_NODE_FUNCTION
);
if
(
NULL
==
pFunc
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
strcpy
(
pFunc
->
functionName
,
"_wduration"
);
return
nodesListAppend
(
pProjectionList
,
(
SNode
*
)
pFunc
);
}
static
int32_t
buildProjectsForSampleAst
(
SSampleAstInfo
*
pInfo
,
SNodeList
**
pList
)
{
SNodeList
*
pProjectionList
=
pInfo
->
pFuncs
;
pInfo
->
pFuncs
=
NULL
;
int32_t
code
=
addWstartToSampleProjects
(
pProjectionList
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
pInfo
->
createSmaIndex
)
{
code
=
addWendToSampleProjects
(
pProjectionList
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
addWdurationToSampleProjects
(
pProjectionList
);
}
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
SNode
*
pProject
=
NULL
;
FOREACH
(
pProject
,
pProjectionList
)
{
sprintf
(((
SExprNode
*
)
pProject
)
->
aliasName
,
"#%p"
,
pProject
);
}
*
pList
=
pProjectionList
;
}
else
{
nodesDestroyList
(
pProjectionList
);
}
return
code
;
}
static
int32_t
buildIntervalForSampleAst
(
SSampleAstInfo
*
pInfo
,
SNode
**
pOutput
)
{
SIntervalWindowNode
*
pInterval
=
(
SIntervalWindowNode
*
)
nodesMakeNode
(
QUERY_NODE_INTERVAL_WINDOW
);
if
(
NULL
==
pInterval
)
{
nodesDestroyNode
((
SNode
*
)
pSelect
);
return
TSDB_CODE_OUT_OF_MEMORY
;
}
pSelect
->
pWindow
=
(
SNode
*
)
pInterval
;
TSWAP
(
pInterval
->
pInterval
,
pInfo
->
pInterval
);
TSWAP
(
pInterval
->
pOffset
,
pInfo
->
pOffset
);
TSWAP
(
pInterval
->
pSliding
,
pInfo
->
pSliding
);
pInterval
->
pCol
=
nodesMakeNode
(
QUERY_NODE_COLUMN
);
if
(
NULL
==
pInterval
->
pCol
)
{
nodesDestroyNode
((
SNode
*
)
p
Select
);
nodesDestroyNode
((
SNode
*
)
p
Interval
);
return
TSDB_CODE_OUT_OF_MEMORY
;
}
((
SColumnNode
*
)
pInterval
->
pCol
)
->
colId
=
PRIMARYKEY_TIMESTAMP_COL_ID
;
strcpy
(((
SColumnNode
*
)
pInterval
->
pCol
)
->
colName
,
ROWTS_PSEUDO_COLUMN_NAME
);
*
pOutput
=
(
SNode
*
)
pInterval
;
return
TSDB_CODE_SUCCESS
;
}
pCxt
->
createStream
=
true
;
int32_t
code
=
translateQuery
(
pCxt
,
(
SNode
*
)
pSelect
);
static
int32_t
buildSampleAst
(
STranslateContext
*
pCxt
,
SSampleAstInfo
*
pInfo
,
char
**
pAst
,
int32_t
*
pLen
,
char
**
pExpr
,
int32_t
*
pExprLen
)
{
SSelectStmt
*
pSelect
=
(
SSelectStmt
*
)
nodesMakeNode
(
QUERY_NODE_SELECT_STMT
);
if
(
NULL
==
pSelect
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
sprintf
(
pSelect
->
stmtName
,
"%p"
,
pSelect
);
int32_t
code
=
buildTableForSampleAst
(
pInfo
,
&
pSelect
->
pFromTable
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
buildProjectsForSampleAst
(
pInfo
,
&
pSelect
->
pProjectionList
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
TSWAP
(
pSelect
->
pPartitionByList
,
pInfo
->
pPartitionByList
);
code
=
buildIntervalForSampleAst
(
pInfo
,
&
pSelect
->
pWindow
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
pCxt
->
createStream
=
true
;
code
=
translateQuery
(
pCxt
,
(
SNode
*
)
pSelect
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesNodeToString
((
SNode
*
)
pSelect
,
false
,
pAst
,
pLen
);
}
...
...
@@ -5162,6 +5213,7 @@ static int32_t getSmaIndexSql(STranslateContext* pCxt, char** pSql, int32_t* pLe
}
static
int32_t
buildSampleAstInfoByIndex
(
STranslateContext
*
pCxt
,
SCreateIndexStmt
*
pStmt
,
SSampleAstInfo
*
pInfo
)
{
pInfo
->
createSmaIndex
=
true
;
pInfo
->
pDbName
=
pStmt
->
dbName
;
pInfo
->
pTableName
=
pStmt
->
tableName
;
pInfo
->
pFuncs
=
nodesCloneList
(
pStmt
->
pOptions
->
pFuncs
);
...
...
source/libs/planner/src/planOptimizer.c
浏览文件 @
0fd30515
...
...
@@ -1284,18 +1284,14 @@ static int32_t smaIndexOptFindSmaFunc(SNode* pQueryFunc, SNodeList* pSmaFuncs) {
return
-
1
;
}
static
int32_t
smaIndexOptCreateSmaCols
(
SNodeList
*
pFuncs
,
uint64_t
tableId
,
SNodeList
*
pSmaFuncs
,
SNodeList
**
pOutput
,
int32_t
*
pWStrartIndex
)
{
static
int32_t
smaIndexOptCreateSmaCols
(
SNodeList
*
pFuncs
,
uint64_t
tableId
,
SNodeList
*
pSmaFuncs
,
SNodeList
**
pOutput
)
{
SNodeList
*
pCols
=
NULL
;
SNode
*
pFunc
=
NULL
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
int32_t
index
=
0
;
int32_t
smaFuncIndex
=
-
1
;
*
pWStrartIndex
=
-
1
;
FOREACH
(
pFunc
,
pFuncs
)
{
if
(
FUNCTION_TYPE_WSTART
==
((
SFunctionNode
*
)
pFunc
)
->
funcType
)
{
*
pWStrartIndex
=
index
;
}
smaFuncIndex
=
smaIndexOptFindSmaFunc
(
pFunc
,
pSmaFuncs
);
if
(
smaFuncIndex
<
0
)
{
break
;
...
...
@@ -1317,8 +1313,7 @@ static int32_t smaIndexOptCreateSmaCols(SNodeList* pFuncs, uint64_t tableId, SNo
return
code
;
}
static
int32_t
smaIndexOptCouldApplyIndex
(
SScanLogicNode
*
pScan
,
STableIndexInfo
*
pIndex
,
SNodeList
**
pCols
,
int32_t
*
pWStrartIndex
)
{
static
int32_t
smaIndexOptCouldApplyIndex
(
SScanLogicNode
*
pScan
,
STableIndexInfo
*
pIndex
,
SNodeList
**
pCols
)
{
SWindowLogicNode
*
pWindow
=
(
SWindowLogicNode
*
)
pScan
->
node
.
pParent
;
if
(
!
smaIndexOptEqualInterval
(
pScan
,
pWindow
,
pIndex
))
{
return
TSDB_CODE_SUCCESS
;
...
...
@@ -1326,14 +1321,14 @@ static int32_t smaIndexOptCouldApplyIndex(SScanLogicNode* pScan, STableIndexInfo
SNodeList
*
pSmaFuncs
=
NULL
;
int32_t
code
=
nodesStringToList
(
pIndex
->
expr
,
&
pSmaFuncs
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
smaIndexOptCreateSmaCols
(
pWindow
->
pFuncs
,
pIndex
->
dstTbUid
,
pSmaFuncs
,
pCols
,
pWStrartIndex
);
code
=
smaIndexOptCreateSmaCols
(
pWindow
->
pFuncs
,
pIndex
->
dstTbUid
,
pSmaFuncs
,
pCols
);
}
nodesDestroyList
(
pSmaFuncs
);
return
code
;
}
static
int32_t
smaIndexOptApplyIndex
(
SLogicSubplan
*
pLogicSubplan
,
SScanLogicNode
*
pScan
,
STableIndexInfo
*
pIndex
,
SNodeList
*
pSmaCols
,
int32_t
wstrartIndex
)
{
SNodeList
*
pSmaCols
)
{
SLogicNode
*
pSmaScan
=
NULL
;
int32_t
code
=
smaIndexOptCreateSmaScan
(
pScan
,
pIndex
,
pSmaCols
,
&
pSmaScan
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
...
...
@@ -1350,10 +1345,9 @@ static int32_t smaIndexOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogi
for
(
int32_t
i
=
0
;
i
<
nindexes
;
++
i
)
{
STableIndexInfo
*
pIndex
=
taosArrayGet
(
pScan
->
pSmaIndexes
,
i
);
SNodeList
*
pSmaCols
=
NULL
;
int32_t
wstrartIndex
=
-
1
;
code
=
smaIndexOptCouldApplyIndex
(
pScan
,
pIndex
,
&
pSmaCols
,
&
wstrartIndex
);
code
=
smaIndexOptCouldApplyIndex
(
pScan
,
pIndex
,
&
pSmaCols
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pSmaCols
)
{
code
=
smaIndexOptApplyIndex
(
pLogicSubplan
,
pScan
,
pIndex
,
pSmaCols
,
wstrartIndex
);
code
=
smaIndexOptApplyIndex
(
pLogicSubplan
,
pScan
,
pIndex
,
pSmaCols
);
taosArrayDestroyEx
(
pScan
->
pSmaIndexes
,
smaIndexOptDestroySmaIndex
);
pScan
->
pSmaIndexes
=
NULL
;
pCxt
->
optimized
=
true
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录