From ef7d78439485d7caca55b59e1f11e5a3c59c736a Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Thu, 7 Apr 2022 19:08:28 +0800 Subject: [PATCH] sort plan bugfix --- include/libs/nodes/plannodes.h | 2 ++ include/libs/nodes/querynodes.h | 1 + source/libs/nodes/src/nodesCodeFuncs.c | 14 ++++++++++++++ source/libs/nodes/src/nodesTraverseFuncs.c | 10 ++++++---- source/libs/parser/src/parTokenizer.c | 3 +++ source/libs/planner/src/planLogicCreater.c | 2 +- source/libs/planner/src/planPhysiCreater.c | 12 ++++++++++-- source/libs/planner/test/plannerTest.cpp | 3 +++ 8 files changed, 40 insertions(+), 7 deletions(-) diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index 65f7e1ceb8..7cb96104bd 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -286,12 +286,14 @@ typedef struct SSortPhysiNode { SPhysiNode node; SNodeList* pExprs; // these are expression list of order_by_clause and parameter expression of aggregate function SNodeList* pSortKeys; // element is SOrderByExprNode, and SOrderByExprNode::pExpr is SColumnNode + SNodeList* pTargets; } SSortPhysiNode; typedef struct SPartitionPhysiNode { SPhysiNode node; SNodeList* pExprs; // these are expression list of partition_by_clause SNodeList* pPartitionKeys; + SNodeList* pTargets; } SPartitionPhysiNode; typedef struct SDataSinkNode { diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index f811b42f2f..f987afd878 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -258,6 +258,7 @@ typedef enum ESqlClause { SQL_CLAUSE_WINDOW, SQL_CLAUSE_GROUP_BY, SQL_CLAUSE_HAVING, + SQL_CLAUSE_DISTINCT, SQL_CLAUSE_SELECT, SQL_CLAUSE_ORDER_BY } ESqlClause; diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 6cb1955307..c3bc696a53 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -994,6 +994,7 @@ static int32_t jsonToPhysiExchangeNode(const SJson* pJson, void* pObj) { static const char* jkSortPhysiPlanExprs = "Exprs"; static const char* jkSortPhysiPlanSortKeys = "SortKeys"; +static const char* jkSortPhysiPlanTargets = "Targets"; static int32_t physiSortNodeToJson(const void* pObj, SJson* pJson) { const SSortPhysiNode* pNode = (const SSortPhysiNode*)pObj; @@ -1005,6 +1006,9 @@ static int32_t physiSortNodeToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = nodeListToJson(pJson, jkSortPhysiPlanSortKeys, pNode->pSortKeys); } + if (TSDB_CODE_SUCCESS == code) { + code = nodeListToJson(pJson, jkSortPhysiPlanTargets, pNode->pTargets); + } return code; } @@ -1019,6 +1023,9 @@ static int32_t jsonToPhysiSortNode(const SJson* pJson, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = jsonToNodeList(pJson, jkSortPhysiPlanSortKeys, &pNode->pSortKeys); } + if (TSDB_CODE_SUCCESS == code) { + code = jsonToNodeList(pJson, jkSortPhysiPlanTargets, &pNode->pTargets); + } return code; } @@ -1177,6 +1184,7 @@ static int32_t jsonToPhysiStateWindowNode(const SJson* pJson, void* pObj) { static const char* jkPartitionPhysiPlanExprs = "Exprs"; static const char* jkPartitionPhysiPlanPartitionKeys = "PartitionKeys"; +static const char* jkPartitionPhysiPlanTargets = "Targets"; static int32_t physiPartitionNodeToJson(const void* pObj, SJson* pJson) { const SPartitionPhysiNode* pNode = (const SPartitionPhysiNode*)pObj; @@ -1188,6 +1196,9 @@ static int32_t physiPartitionNodeToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = nodeListToJson(pJson, jkPartitionPhysiPlanPartitionKeys, pNode->pPartitionKeys); } + if (TSDB_CODE_SUCCESS == code) { + code = nodeListToJson(pJson, jkPartitionPhysiPlanTargets, pNode->pTargets); + } return code; } @@ -1202,6 +1213,9 @@ static int32_t jsonToPhysiPartitionNode(const SJson* pJson, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = jsonToNodeList(pJson, jkPartitionPhysiPlanPartitionKeys, &pNode->pPartitionKeys); } + if (TSDB_CODE_SUCCESS == code) { + code = jsonToNodeList(pJson, jkPartitionPhysiPlanTargets, &pNode->pTargets); + } return code; } diff --git a/source/libs/nodes/src/nodesTraverseFuncs.c b/source/libs/nodes/src/nodesTraverseFuncs.c index e59a76ca3c..3c10287992 100644 --- a/source/libs/nodes/src/nodesTraverseFuncs.c +++ b/source/libs/nodes/src/nodesTraverseFuncs.c @@ -301,9 +301,10 @@ void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker wa case SQL_CLAUSE_GROUP_BY: nodesWalkExpr(pSelect->pHaving, walker, pContext); case SQL_CLAUSE_HAVING: - nodesWalkExprs(pSelect->pProjectionList, walker, pContext); - case SQL_CLAUSE_SELECT: + case SQL_CLAUSE_DISTINCT: nodesWalkExprs(pSelect->pOrderByList, walker, pContext); + case SQL_CLAUSE_ORDER_BY: + nodesWalkExprs(pSelect->pProjectionList, walker, pContext); default: break; } @@ -329,9 +330,10 @@ void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewrit case SQL_CLAUSE_GROUP_BY: nodesRewriteExpr(&(pSelect->pHaving), rewriter, pContext); case SQL_CLAUSE_HAVING: - nodesRewriteExprs(pSelect->pProjectionList, rewriter, pContext); - case SQL_CLAUSE_SELECT: + case SQL_CLAUSE_DISTINCT: nodesRewriteExprs(pSelect->pOrderByList, rewriter, pContext); + case SQL_CLAUSE_ORDER_BY: + nodesRewriteExprs(pSelect->pProjectionList, rewriter, pContext); default: break; } diff --git a/source/libs/parser/src/parTokenizer.c b/source/libs/parser/src/parTokenizer.c index 21191563e1..300c41f73f 100644 --- a/source/libs/parser/src/parTokenizer.c +++ b/source/libs/parser/src/parTokenizer.c @@ -72,6 +72,7 @@ static SKeyword keywordTable[] = { {"EXPLAIN", TK_EXPLAIN}, {"FILE_FACTOR", TK_FILE_FACTOR}, {"FILL", TK_FILL}, + {"FIRST", TK_FIRST}, {"FLOAT", TK_FLOAT}, {"FROM", TK_FROM}, {"FSYNC", TK_FSYNC}, @@ -95,6 +96,7 @@ static SKeyword keywordTable[] = { {"JSON", TK_JSON}, {"KEEP", TK_KEEP}, {"KILL", TK_KILL}, + {"LAST", TK_LAST}, {"LICENCE", TK_LICENCE}, {"LIKE", TK_LIKE}, {"LIMIT", TK_LIMIT}, @@ -113,6 +115,7 @@ static SKeyword keywordTable[] = { {"NOT", TK_NOT}, {"NOW", TK_NOW}, {"NULL", TK_NULL}, + {"NULLS", TK_NULLS}, {"OFFSET", TK_OFFSET}, {"ON", TK_ON}, {"OR", TK_OR}, diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index 819eb6d699..6832cdce7a 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -701,7 +701,7 @@ static int32_t createDistinctLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSe // rewrite the expression in subsequent clauses if (TSDB_CODE_SUCCESS == code) { - code = rewriteExpr(pAgg->pGroupKeys, pSelect, SQL_CLAUSE_SELECT); + code = rewriteExpr(pAgg->pGroupKeys, pSelect, SQL_CLAUSE_DISTINCT); } // set the output diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 965c5c9579..0c2cffa399 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -928,8 +928,12 @@ static int32_t createSortPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren if (TSDB_CODE_SUCCESS == code) { code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pSortKeys, &pSort->pSortKeys); + } + + if (TSDB_CODE_SUCCESS == code) { + code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pSortLogicNode->node.pTargets, &pSort->pTargets); if (TSDB_CODE_SUCCESS == code) { - code = addDataBlockSlots(pCxt, pSort->pSortKeys, pSort->node.pOutputDataBlockDesc); + code = addDataBlockSlots(pCxt, pSort->pTargets, pSort->node.pOutputDataBlockDesc); } } @@ -963,8 +967,12 @@ static int32_t createPartitionPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChi if (TSDB_CODE_SUCCESS == code) { code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pPartitionKeys, &pPart->pPartitionKeys); + } + + if (TSDB_CODE_SUCCESS == code) { + code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pPartLogicNode->node.pTargets, &pPart->pTargets); if (TSDB_CODE_SUCCESS == code) { - code = addDataBlockSlots(pCxt, pPart->pPartitionKeys, pPart->node.pOutputDataBlockDesc); + code = addDataBlockSlots(pCxt, pPart->pTargets, pPart->node.pOutputDataBlockDesc); } } diff --git a/source/libs/planner/test/plannerTest.cpp b/source/libs/planner/test/plannerTest.cpp index 7f79fc6a5a..5f84eec36a 100644 --- a/source/libs/planner/test/plannerTest.cpp +++ b/source/libs/planner/test/plannerTest.cpp @@ -254,6 +254,9 @@ TEST_F(PlannerTest, orderBy) { bind("SELECT * FROM t1 order by c1 + 10, c2"); ASSERT_TRUE(run()); + + bind("SELECT * FROM t1 order by c1 desc nulls first"); + ASSERT_TRUE(run()); } TEST_F(PlannerTest, distinct) { -- GitLab