Instead of deoptimizing limitCount/limitOffset, pass around the original nodes too. Use those nodes for constructing queries which will eventually go through standard_planner again. This still is failing to work with task-tracker

pull/3746/head
Philip Dubé 2020-04-13 18:58:54 +00:00
parent 4dcbb9f82b
commit 004bfca7b2
6 changed files with 27 additions and 29 deletions

View File

@ -266,19 +266,6 @@ distributed_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
* which we're unable to handle. Meanwhile we only optimize rewrites to Const.
* So deoptimize non-Const LIMIT/OFFSET, standard_planner will handle it again later.
*/
if (planContext.query->limitCount &&
!IsA(planContext.query->limitCount, Const))
{
planContext.query->limitCount = planContext.originalQuery->limitCount;
}
if (planContext.query->limitOffset &&
!IsA(planContext.query->limitOffset, Const))
{
planContext.query->limitOffset =
planContext.originalQuery->limitOffset;
}
result = PlanDistributedStmt(&planContext, rteIdCounter);
}
else if ((result = TryToDelegateFunctionCall(&planContext)) == NULL)

View File

@ -1486,6 +1486,8 @@ MasterExtendedOpNode(MultiExtendedOp *originalOpNode,
masterExtendedOpNode->sortClauseList = originalOpNode->sortClauseList;
masterExtendedOpNode->distinctClause = originalOpNode->distinctClause;
masterExtendedOpNode->hasDistinctOn = originalOpNode->hasDistinctOn;
masterExtendedOpNode->originalLimitCount = originalOpNode->originalLimitCount;
masterExtendedOpNode->originalLimitOffset = originalOpNode->originalLimitOffset;
masterExtendedOpNode->limitCount = originalOpNode->limitCount;
masterExtendedOpNode->limitOffset = originalOpNode->limitOffset;
masterExtendedOpNode->havingQual = newHavingQual;
@ -2314,6 +2316,7 @@ WorkerExtendedOpNode(MultiExtendedOp *originalOpNode,
workerExtendedOpNode->hasWindowFuncs = queryWindowClause.hasWindowFunctions;
workerExtendedOpNode->windowClause = queryWindowClause.workerWindowClauseList;
workerExtendedOpNode->sortClauseList = queryOrderByLimit.workerSortClauseList;
workerExtendedOpNode->originalLimitCount = queryOrderByLimit.workerLimitCount;
workerExtendedOpNode->limitCount = queryOrderByLimit.workerLimitCount;
return workerExtendedOpNode;

View File

@ -157,7 +157,7 @@ MultiLogicalPlanCreate(Query *originalQuery, Query *queryTree,
}
else
{
multiQueryNode = MultiNodeTree(queryTree);
multiQueryNode = MultiNodeTree(originalQuery, queryTree);
}
/* add a root node to serve as the permanent handle to the tree */
@ -640,7 +640,7 @@ SubqueryEntryList(Query *queryTree)
* group, and limit nodes if they appear in the original query tree.
*/
MultiNode *
MultiNodeTree(Query *queryTree)
MultiNodeTree(Query *originalQuery, Query *queryTree)
{
List *rangeTableList = queryTree->rtable;
List *targetEntryList = queryTree->targetList;
@ -672,7 +672,7 @@ MultiNodeTree(Query *queryTree)
* If we have a subquery, build a multi table node for the subquery and
* add a collect node on top of the multi table node.
*/
List *subqueryEntryList = SubqueryEntryList(queryTree);
List *subqueryEntryList = SubqueryEntryList(originalQuery);
if (subqueryEntryList != NIL)
{
MultiCollect *subqueryCollectNode = CitusMakeNode(MultiCollect);
@ -715,7 +715,7 @@ MultiNodeTree(Query *queryTree)
}
/* recursively create child nested multitree */
MultiNode *subqueryExtendedNode = MultiNodeTree(subqueryTree);
MultiNode *subqueryExtendedNode = MultiNodeTree(subqueryTree, subqueryTree);
SetChild((MultiUnaryNode *) subqueryCollectNode, (MultiNode *) subqueryNode);
SetChild((MultiUnaryNode *) subqueryNode, subqueryExtendedNode);
@ -769,7 +769,7 @@ MultiNodeTree(Query *queryTree)
* distinguish between aggregates and expressions; and we address this later
* in the logical optimizer.
*/
MultiExtendedOp *extendedOpNode = MultiExtendedOpNode(queryTree, queryTree);
MultiExtendedOp *extendedOpNode = MultiExtendedOpNode(originalQuery, queryTree);
SetChild((MultiUnaryNode *) extendedOpNode, currentTopNode);
currentTopNode = (MultiNode *) extendedOpNode;
@ -1821,12 +1821,14 @@ MultiProjectNode(List *targetEntryList)
/* Builds the extended operator node using fields from the given query tree. */
MultiExtendedOp *
MultiExtendedOpNode(Query *queryTree, Query *originalQuery)
MultiExtendedOpNode(Query *originalQuery, Query *queryTree)
{
MultiExtendedOp *extendedOpNode = CitusMakeNode(MultiExtendedOp);
extendedOpNode->targetList = queryTree->targetList;
extendedOpNode->groupClauseList = queryTree->groupClause;
extendedOpNode->sortClauseList = queryTree->sortClause;
extendedOpNode->originalLimitCount = originalQuery->limitCount;
extendedOpNode->originalLimitOffset = originalQuery->limitOffset;
extendedOpNode->limitCount = queryTree->limitCount;
extendedOpNode->limitOffset = queryTree->limitOffset;
extendedOpNode->havingQual = queryTree->havingQual;

View File

@ -666,8 +666,8 @@ BuildJobQuery(MultiNode *multiNode, List *dependentJobList)
{
MultiExtendedOp *extendedOp = (MultiExtendedOp *) linitial(extendedOpNodeList);
limitCount = extendedOp->limitCount;
limitOffset = extendedOp->limitOffset;
limitCount = extendedOp->originalLimitCount;
limitOffset = extendedOp->originalLimitOffset;
sortClauseList = extendedOp->sortClauseList;
havingQual = extendedOp->havingQual;
}
@ -814,8 +814,8 @@ BuildReduceQuery(MultiExtendedOp *extendedOpNode, List *dependentJobList)
reduceQuery->jointree = joinTree;
reduceQuery->sortClause = extendedOpNode->sortClauseList;
reduceQuery->groupClause = extendedOpNode->groupClauseList;
reduceQuery->limitOffset = extendedOpNode->limitOffset;
reduceQuery->limitCount = extendedOpNode->limitCount;
reduceQuery->limitOffset = extendedOpNode->originalLimitOffset;
reduceQuery->limitCount = extendedOpNode->originalLimitCount;
reduceQuery->havingQual = extendedOpNode->havingQual;
reduceQuery->hasAggs = contain_aggs_of_level((Node *) targetList, 0);
@ -1551,8 +1551,8 @@ BuildSubqueryJobQuery(MultiNode *multiNode)
{
MultiExtendedOp *extendedOp = (MultiExtendedOp *) linitial(extendedOpNodeList);
limitCount = extendedOp->limitCount;
limitOffset = extendedOp->limitOffset;
limitCount = extendedOp->originalLimitCount;
limitOffset = extendedOp->originalLimitOffset;
sortClauseList = extendedOp->sortClauseList;
havingQual = extendedOp->havingQual;
distinctClause = extendedOp->distinctClause;

View File

@ -551,7 +551,7 @@ SubqueryMultiNodeTree(Query *originalQuery, Query *queryTree,
}
/* all checks have passed, safe to create the multi plan */
multiQueryNode = MultiNodeTree(queryTree);
multiQueryNode = MultiNodeTree(originalQuery, queryTree);
}
Assert(multiQueryNode != NULL);
@ -1623,7 +1623,7 @@ SubqueryPushdownMultiNodeTree(Query *originalQuery)
* distinguish between aggregates and expressions; and we address this later
* in the logical optimizer.
*/
MultiExtendedOp *extendedOpNode = MultiExtendedOpNode(queryTree, originalQuery);
MultiExtendedOp *extendedOpNode = MultiExtendedOpNode(originalQuery, queryTree);
/*
* Postgres standard planner converts having qual node to a list of and
@ -1665,6 +1665,10 @@ SubqueryPushdownMultiNodeTree(Query *originalQuery)
* expression on the LIMIT and OFFSET clauses. Note that logical optimizer
* expects those clauses to be already evaluated.
*/
extendedOpNode->originalLimitCount =
PartiallyEvaluateExpression(extendedOpNode->originalLimitCount, NULL);
extendedOpNode->originalLimitOffset =
PartiallyEvaluateExpression(extendedOpNode->originalLimitOffset, NULL);
extendedOpNode->limitCount =
PartiallyEvaluateExpression(extendedOpNode->limitCount, NULL);
extendedOpNode->limitOffset =

View File

@ -172,6 +172,8 @@ typedef struct MultiExtendedOp
List *targetList;
List *groupClauseList;
List *sortClauseList;
Node *originalLimitCount;
Node *originalLimitOffset;
Node *limitCount;
Node *limitOffset;
Node *havingQual;
@ -219,10 +221,10 @@ extern List * pull_var_clause_default(Node *node);
extern bool OperatorImplementsEquality(Oid opno);
extern DeferredErrorMessage * DeferErrorIfUnsupportedClause(List *clauseList);
extern MultiProject * MultiProjectNode(List *targetEntryList);
extern MultiExtendedOp * MultiExtendedOpNode(Query *queryTree, Query *originalQuery);
extern MultiExtendedOp * MultiExtendedOpNode(Query *originalQuery, Query *queryTree);
extern DeferredErrorMessage * DeferErrorIfUnsupportedSubqueryRepartition(Query *
subqueryTree);
extern MultiNode * MultiNodeTree(Query *queryTree);
extern MultiNode * MultiNodeTree(Query *originalQuery, Query *queryTree);
#endif /* MULTI_LOGICAL_PLANNER_H */