Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
bcadc8d8
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看板
未验证
提交
bcadc8d8
编写于
7月 17, 2023
作者:
D
dapan1121
提交者:
GitHub
7月 17, 2023
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #22070 from wangjiaming0909/fix/m/TS-3671
fix: state/session/event window with order by _wstart/_wend has no effect
上级
f2ee9922
b850c1af
变更
5
展开全部
隐藏空白更改
内联
并排
Showing
5 changed file
with
1258 addition
and
19 deletion
+1258
-19
include/libs/nodes/plannodes.h
include/libs/nodes/plannodes.h
+1
-0
source/libs/planner/src/planLogicCreater.c
source/libs/planner/src/planLogicCreater.c
+1
-1
source/libs/planner/src/planOptimizer.c
source/libs/planner/src/planOptimizer.c
+34
-18
tests/script/tsim/query/r/explain_tsorder.result
tests/script/tsim/query/r/explain_tsorder.result
+1160
-0
tests/script/tsim/query/t/explain_tsorder.sql
tests/script/tsim/query/t/explain_tsorder.sql
+62
-0
未找到文件。
include/libs/nodes/plannodes.h
浏览文件 @
bcadc8d8
...
...
@@ -247,6 +247,7 @@ typedef struct SSortLogicNode {
SNodeList
*
pSortKeys
;
bool
groupSort
;
int64_t
maxRows
;
bool
skipPKSortOpt
;
}
SSortLogicNode
;
typedef
struct
SPartitionLogicNode
{
...
...
source/libs/planner/src/planLogicCreater.c
浏览文件 @
bcadc8d8
...
...
@@ -1034,7 +1034,6 @@ static int32_t createSortLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
pSort
->
node
.
resultDataOrder
=
isPrimaryKeySort
(
pSelect
->
pOrderByList
)
?
(
pSort
->
groupSort
?
DATA_ORDER_LEVEL_IN_GROUP
:
DATA_ORDER_LEVEL_GLOBAL
)
:
DATA_ORDER_LEVEL_NONE
;
int32_t
code
=
nodesCollectColumns
(
pSelect
,
SQL_CLAUSE_ORDER_BY
,
NULL
,
COLLECT_COL_TYPE_ALL
,
&
pSort
->
node
.
pTargets
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
==
pSort
->
node
.
pTargets
)
{
code
=
nodesListMakeStrictAppend
(
&
pSort
->
node
.
pTargets
,
...
...
@@ -1048,6 +1047,7 @@ static int32_t createSortLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
}
SNode
*
pNode
=
NULL
;
SOrderByExprNode
*
firstSortKey
=
(
SOrderByExprNode
*
)
nodesListGetNode
(
pSort
->
pSortKeys
,
0
);
if
(
isPrimaryKeySort
(
pSelect
->
pOrderByList
))
pSort
->
node
.
outputTsOrder
=
firstSortKey
->
order
;
if
(
firstSortKey
->
pExpr
->
type
==
QUERY_NODE_COLUMN
)
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
firstSortKey
->
pExpr
;
int16_t
projIdx
=
1
;
...
...
source/libs/planner/src/planOptimizer.c
浏览文件 @
bcadc8d8
...
...
@@ -1168,7 +1168,8 @@ static bool sortPriKeyOptMayBeOptimized(SLogicNode* pNode) {
return
false
;
}
SSortLogicNode
*
pSort
=
(
SSortLogicNode
*
)
pNode
;
if
(
!
sortPriKeyOptIsPriKeyOrderBy
(
pSort
->
pSortKeys
)
||
1
!=
LIST_LENGTH
(
pSort
->
node
.
pChildren
))
{
if
(
pSort
->
skipPKSortOpt
||
!
sortPriKeyOptIsPriKeyOrderBy
(
pSort
->
pSortKeys
)
||
1
!=
LIST_LENGTH
(
pSort
->
node
.
pChildren
))
{
return
false
;
}
SNode
*
pChild
;
...
...
@@ -1181,8 +1182,8 @@ static bool sortPriKeyOptMayBeOptimized(SLogicNode* pNode) {
return
true
;
}
static
int32_t
sortPriKeyOptGetSequencingNodesImpl
(
SLogicNode
*
pNode
,
bool
groupSort
,
bool
*
pNotOptimize
,
SNodeList
**
pSequencingNodes
)
{
static
int32_t
sortPriKeyOptGetSequencingNodesImpl
(
SLogicNode
*
pNode
,
bool
groupSort
,
EOrder
sortOrder
,
bool
*
pNotOptimize
,
SNodeList
**
pSequencingNodes
)
{
if
(
NULL
!=
pNode
->
pLimit
||
NULL
!=
pNode
->
pSlimit
)
{
*
pNotOptimize
=
false
;
return
TSDB_CODE_SUCCESS
;
...
...
@@ -1199,15 +1200,21 @@ static int32_t sortPriKeyOptGetSequencingNodesImpl(SLogicNode* pNode, bool group
}
case
QUERY_NODE_LOGIC_PLAN_JOIN
:
{
int32_t
code
=
sortPriKeyOptGetSequencingNodesImpl
((
SLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
0
),
groupSort
,
pNotOptimize
,
pSequencingNodes
);
sortOrder
,
pNotOptimize
,
pSequencingNodes
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
sortPriKeyOptGetSequencingNodesImpl
((
SLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
1
),
groupSort
,
pNotOptimize
,
pSequencingNodes
);
sortOrder
,
pNotOptimize
,
pSequencingNodes
);
}
return
code
;
}
case
QUERY_NODE_LOGIC_PLAN_WINDOW
:
return
nodesListMakeAppend
(
pSequencingNodes
,
(
SNode
*
)
pNode
);
case
QUERY_NODE_LOGIC_PLAN_WINDOW
:
{
SWindowLogicNode
*
pWindowLogicNode
=
(
SWindowLogicNode
*
)
pNode
;
// For interval window, we always apply sortPriKey optimization.
// For session/event/state window, the output ts order will always be ASC.
// If sort order is also asc, we apply optimization, otherwise we keep sort node to get correct output order.
if
(
pWindowLogicNode
->
winType
==
WINDOW_TYPE_INTERVAL
||
sortOrder
==
ORDER_ASC
)
return
nodesListMakeAppend
(
pSequencingNodes
,
(
SNode
*
)
pNode
);
}
case
QUERY_NODE_LOGIC_PLAN_AGG
:
case
QUERY_NODE_LOGIC_PLAN_PARTITION
:
*
pNotOptimize
=
true
;
...
...
@@ -1221,23 +1228,25 @@ static int32_t sortPriKeyOptGetSequencingNodesImpl(SLogicNode* pNode, bool group
return
TSDB_CODE_SUCCESS
;
}
return
sortPriKeyOptGetSequencingNodesImpl
((
SLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
0
),
groupSort
,
return
sortPriKeyOptGetSequencingNodesImpl
((
SLogicNode
*
)
nodesListGetNode
(
pNode
->
pChildren
,
0
),
groupSort
,
sortOrder
,
pNotOptimize
,
pSequencingNodes
);
}
static
int32_t
sortPriKeyOptGetSequencingNodes
(
SLogicNode
*
pNode
,
bool
groupSort
,
SNodeList
**
pSequencingNodes
)
{
static
EOrder
sortPriKeyOptGetPriKeyOrder
(
SSortLogicNode
*
pSort
)
{
return
((
SOrderByExprNode
*
)
nodesListGetNode
(
pSort
->
pSortKeys
,
0
))
->
order
;
}
static
int32_t
sortPriKeyOptGetSequencingNodes
(
SSortLogicNode
*
pSort
,
bool
groupSort
,
SNodeList
**
pSequencingNodes
)
{
bool
notOptimize
=
false
;
int32_t
code
=
sortPriKeyOptGetSequencingNodesImpl
(
pNode
,
groupSort
,
&
notOptimize
,
pSequencingNodes
);
int32_t
code
=
sortPriKeyOptGetSequencingNodesImpl
((
SLogicNode
*
)
nodesListGetNode
(
pSort
->
node
.
pChildren
,
0
),
groupSort
,
sortPriKeyOptGetPriKeyOrder
(
pSort
),
&
notOptimize
,
pSequencingNodes
);
if
(
TSDB_CODE_SUCCESS
!=
code
||
notOptimize
)
{
NODES_CLEAR_LIST
(
*
pSequencingNodes
);
}
return
code
;
}
static
EOrder
sortPriKeyOptGetPriKeyOrder
(
SSortLogicNode
*
pSort
)
{
return
((
SOrderByExprNode
*
)
nodesListGetNode
(
pSort
->
pSortKeys
,
0
))
->
order
;
}
static
int32_t
sortPriKeyOptApply
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
,
SSortLogicNode
*
pSort
,
SNodeList
*
pSequencingNodes
)
{
EOrder
order
=
sortPriKeyOptGetPriKeyOrder
(
pSort
);
...
...
@@ -1276,10 +1285,17 @@ static int32_t sortPriKeyOptApply(SOptimizeContext* pCxt, SLogicSubplan* pLogicS
static
int32_t
sortPrimaryKeyOptimizeImpl
(
SOptimizeContext
*
pCxt
,
SLogicSubplan
*
pLogicSubplan
,
SSortLogicNode
*
pSort
)
{
SNodeList
*
pSequencingNodes
=
NULL
;
int32_t
code
=
sortPriKeyOptGetSequencingNodes
((
SLogicNode
*
)
nodesListGetNode
(
pSort
->
node
.
pChildren
,
0
),
pSort
->
groupSort
,
&
pSequencingNodes
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pSequencingNodes
)
{
code
=
sortPriKeyOptApply
(
pCxt
,
pLogicSubplan
,
pSort
,
pSequencingNodes
);
int32_t
code
=
sortPriKeyOptGetSequencingNodes
(
pSort
,
pSort
->
groupSort
,
&
pSequencingNodes
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
if
(
pSequencingNodes
!=
NULL
)
{
code
=
sortPriKeyOptApply
(
pCxt
,
pLogicSubplan
,
pSort
,
pSequencingNodes
);
}
else
{
// if we decided not to push down sort info to children, we should propagate output ts order to parents of pSort
optSetParentOrder
(
pSort
->
node
.
pParent
,
sortPriKeyOptGetPriKeyOrder
(
pSort
),
0
);
// we need to prevent this pSort from being chosen to do optimization again
pSort
->
skipPKSortOpt
=
true
;
pCxt
->
optimized
=
true
;
}
}
nodesClearList
(
pSequencingNodes
);
return
code
;
...
...
tests/script/tsim/query/r/explain_tsorder.result
浏览文件 @
bcadc8d8
此差异已折叠。
点击以展开。
tests/script/tsim/query/t/explain_tsorder.sql
浏览文件 @
bcadc8d8
...
...
@@ -98,3 +98,65 @@ select last(ts), c2 as d from d1 group by c2 order by c2 asc limit 9,1;
select
last
(
ts
)
as
ts
,
c2
as
d
from
d1
group
by
c2
order
by
ts
desc
,
c2
asc
limit
10
;
select
last
(
ts
)
as
ts
,
c2
as
d
from
d1
group
by
c2
order
by
ts
desc
,
c2
asc
limit
2
,
8
;
select
last
(
ts
)
as
ts
,
c2
as
d
from
d1
group
by
c2
order
by
ts
desc
,
c2
asc
limit
9
,
1
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
event_window
start
with
c2
>
0
end
with
c2
<
100
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
event_window
start
with
c2
>
0
end
with
c2
<
100
order
by
_wstart
desc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
event_window
start
with
c2
>
0
end
with
c2
<
100
order
by
_wstart
asc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
event_window
start
with
c2
>
0
end
with
c2
<
100
order
by
_wend
desc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
event_window
start
with
c2
>
0
end
with
c2
<
100
order
by
_wend
asc
\
G
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
event_window
start
with
c2
>
0
end
with
c2
<
100
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
event_window
start
with
c2
>
0
end
with
c2
<
100
order
by
_wstart
desc
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
event_window
start
with
c2
>
0
end
with
c2
<
100
order
by
_wstart
asc
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
event_window
start
with
c2
>
0
end
with
c2
<
100
order
by
_wend
desc
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
event_window
start
with
c2
>
0
end
with
c2
<
100
order
by
_wend
asc
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wstart
desc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wstart
asc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wend
desc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wend
asc
\
G
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
);
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wstart
desc
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wstart
asc
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wend
desc
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wend
asc
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wstart
desc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wstart
asc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wend
desc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wend
asc
\
G
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
);
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wstart
desc
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wstart
asc
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wend
desc
;
select
_wstart
,
_wend
,
count
(
*
)
from
meters
session
(
ts
,
1
h
)
order
by
_wend
asc
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
)
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
)
order
by
_wstart
desc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
)
order
by
_wstart
asc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
)
order
by
_wend
desc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
)
order
by
_wend
asc
\
G
;
select
_wstart
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
);
select
_wstart
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
)
order
by
_wstart
desc
;
select
_wstart
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
)
order
by
_wstart
asc
;
select
_wstart
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
)
order
by
_wend
desc
;
select
_wstart
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
)
order
by
_wend
asc
;
explain
verbose
true
select
_wstart
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
)
order
by
_wend
asc
,
count
(
*
)
desc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
last
(
ts
)
from
(
select
_wstart
as
ts
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
)
order
by
_wend
desc
)
interval
(
1
h
)
order
by
_wstart
desc
\
G
;
explain
verbose
true
select
_wstart
,
_wend
,
last
(
ts
)
from
(
select
_wstart
as
ts
,
_wend
,
count
(
*
),
last
(
ts
)
from
meters
state_window
(
c2
)
order
by
_wend
asc
)
interval
(
1
h
)
order
by
_wstart
desc
\
G
;
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录