Merge pull request #22070 from wangjiaming0909/fix/m/TS-3671
fix: state/session/event window with order by _wstart/_wend has no effect
This commit is contained in:
commit
bcadc8d85b
|
@ -247,6 +247,7 @@ typedef struct SSortLogicNode {
|
|||
SNodeList* pSortKeys;
|
||||
bool groupSort;
|
||||
int64_t maxRows;
|
||||
bool skipPKSortOpt;
|
||||
} SSortLogicNode;
|
||||
|
||||
typedef struct SPartitionLogicNode {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
bool notOptimize = false;
|
||||
int32_t code = sortPriKeyOptGetSequencingNodesImpl(pNode, groupSort, ¬Optimize, 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 sortPriKeyOptGetSequencingNodes(SSortLogicNode* pSort, bool groupSort, SNodeList** pSequencingNodes) {
|
||||
bool notOptimize = false;
|
||||
int32_t code =
|
||||
sortPriKeyOptGetSequencingNodesImpl((SLogicNode*)nodesListGetNode(pSort->node.pChildren, 0), groupSort,
|
||||
sortPriKeyOptGetPriKeyOrder(pSort), ¬Optimize, pSequencingNodes);
|
||||
if (TSDB_CODE_SUCCESS != code || notOptimize) {
|
||||
NODES_CLEAR_LIST(*pSequencingNodes);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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, 1h)\G;
|
||||
explain verbose true select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wstart desc\G;
|
||||
explain verbose true select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wstart asc\G;
|
||||
|
||||
explain verbose true select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wend desc\G;
|
||||
explain verbose true select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wend asc\G;
|
||||
|
||||
select _wstart, _wend, count(*) from meters session(ts, 1h);
|
||||
select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wstart desc;
|
||||
select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wstart asc;
|
||||
|
||||
select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wend desc;
|
||||
select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wend asc;
|
||||
|
||||
|
||||
explain verbose true select _wstart, _wend, count(*) from meters session(ts, 1h)\G;
|
||||
explain verbose true select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wstart desc\G;
|
||||
explain verbose true select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wstart asc\G;
|
||||
|
||||
explain verbose true select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wend desc\G;
|
||||
explain verbose true select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wend asc\G;
|
||||
|
||||
select _wstart, _wend, count(*) from meters session(ts, 1h);
|
||||
select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wstart desc;
|
||||
select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wstart asc;
|
||||
|
||||
select _wstart, _wend, count(*) from meters session(ts, 1h) order by _wend desc;
|
||||
select _wstart, _wend, count(*) from meters session(ts, 1h) 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(1h) 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(1h) order by _wstart desc\G;
|
||||
|
|
Loading…
Reference in New Issue