mirror of https://github.com/citusdata/citus.git
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
parent
4dcbb9f82b
commit
004bfca7b2
|
@ -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.
|
* 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.
|
* 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);
|
result = PlanDistributedStmt(&planContext, rteIdCounter);
|
||||||
}
|
}
|
||||||
else if ((result = TryToDelegateFunctionCall(&planContext)) == NULL)
|
else if ((result = TryToDelegateFunctionCall(&planContext)) == NULL)
|
||||||
|
|
|
@ -1486,6 +1486,8 @@ MasterExtendedOpNode(MultiExtendedOp *originalOpNode,
|
||||||
masterExtendedOpNode->sortClauseList = originalOpNode->sortClauseList;
|
masterExtendedOpNode->sortClauseList = originalOpNode->sortClauseList;
|
||||||
masterExtendedOpNode->distinctClause = originalOpNode->distinctClause;
|
masterExtendedOpNode->distinctClause = originalOpNode->distinctClause;
|
||||||
masterExtendedOpNode->hasDistinctOn = originalOpNode->hasDistinctOn;
|
masterExtendedOpNode->hasDistinctOn = originalOpNode->hasDistinctOn;
|
||||||
|
masterExtendedOpNode->originalLimitCount = originalOpNode->originalLimitCount;
|
||||||
|
masterExtendedOpNode->originalLimitOffset = originalOpNode->originalLimitOffset;
|
||||||
masterExtendedOpNode->limitCount = originalOpNode->limitCount;
|
masterExtendedOpNode->limitCount = originalOpNode->limitCount;
|
||||||
masterExtendedOpNode->limitOffset = originalOpNode->limitOffset;
|
masterExtendedOpNode->limitOffset = originalOpNode->limitOffset;
|
||||||
masterExtendedOpNode->havingQual = newHavingQual;
|
masterExtendedOpNode->havingQual = newHavingQual;
|
||||||
|
@ -2314,6 +2316,7 @@ WorkerExtendedOpNode(MultiExtendedOp *originalOpNode,
|
||||||
workerExtendedOpNode->hasWindowFuncs = queryWindowClause.hasWindowFunctions;
|
workerExtendedOpNode->hasWindowFuncs = queryWindowClause.hasWindowFunctions;
|
||||||
workerExtendedOpNode->windowClause = queryWindowClause.workerWindowClauseList;
|
workerExtendedOpNode->windowClause = queryWindowClause.workerWindowClauseList;
|
||||||
workerExtendedOpNode->sortClauseList = queryOrderByLimit.workerSortClauseList;
|
workerExtendedOpNode->sortClauseList = queryOrderByLimit.workerSortClauseList;
|
||||||
|
workerExtendedOpNode->originalLimitCount = queryOrderByLimit.workerLimitCount;
|
||||||
workerExtendedOpNode->limitCount = queryOrderByLimit.workerLimitCount;
|
workerExtendedOpNode->limitCount = queryOrderByLimit.workerLimitCount;
|
||||||
|
|
||||||
return workerExtendedOpNode;
|
return workerExtendedOpNode;
|
||||||
|
|
|
@ -157,7 +157,7 @@ MultiLogicalPlanCreate(Query *originalQuery, Query *queryTree,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
multiQueryNode = MultiNodeTree(queryTree);
|
multiQueryNode = MultiNodeTree(originalQuery, queryTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add a root node to serve as the permanent handle to the tree */
|
/* 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.
|
* group, and limit nodes if they appear in the original query tree.
|
||||||
*/
|
*/
|
||||||
MultiNode *
|
MultiNode *
|
||||||
MultiNodeTree(Query *queryTree)
|
MultiNodeTree(Query *originalQuery, Query *queryTree)
|
||||||
{
|
{
|
||||||
List *rangeTableList = queryTree->rtable;
|
List *rangeTableList = queryTree->rtable;
|
||||||
List *targetEntryList = queryTree->targetList;
|
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
|
* 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.
|
* add a collect node on top of the multi table node.
|
||||||
*/
|
*/
|
||||||
List *subqueryEntryList = SubqueryEntryList(queryTree);
|
List *subqueryEntryList = SubqueryEntryList(originalQuery);
|
||||||
if (subqueryEntryList != NIL)
|
if (subqueryEntryList != NIL)
|
||||||
{
|
{
|
||||||
MultiCollect *subqueryCollectNode = CitusMakeNode(MultiCollect);
|
MultiCollect *subqueryCollectNode = CitusMakeNode(MultiCollect);
|
||||||
|
@ -715,7 +715,7 @@ MultiNodeTree(Query *queryTree)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* recursively create child nested multitree */
|
/* recursively create child nested multitree */
|
||||||
MultiNode *subqueryExtendedNode = MultiNodeTree(subqueryTree);
|
MultiNode *subqueryExtendedNode = MultiNodeTree(subqueryTree, subqueryTree);
|
||||||
|
|
||||||
SetChild((MultiUnaryNode *) subqueryCollectNode, (MultiNode *) subqueryNode);
|
SetChild((MultiUnaryNode *) subqueryCollectNode, (MultiNode *) subqueryNode);
|
||||||
SetChild((MultiUnaryNode *) subqueryNode, subqueryExtendedNode);
|
SetChild((MultiUnaryNode *) subqueryNode, subqueryExtendedNode);
|
||||||
|
@ -769,7 +769,7 @@ MultiNodeTree(Query *queryTree)
|
||||||
* distinguish between aggregates and expressions; and we address this later
|
* distinguish between aggregates and expressions; and we address this later
|
||||||
* in the logical optimizer.
|
* in the logical optimizer.
|
||||||
*/
|
*/
|
||||||
MultiExtendedOp *extendedOpNode = MultiExtendedOpNode(queryTree, queryTree);
|
MultiExtendedOp *extendedOpNode = MultiExtendedOpNode(originalQuery, queryTree);
|
||||||
SetChild((MultiUnaryNode *) extendedOpNode, currentTopNode);
|
SetChild((MultiUnaryNode *) extendedOpNode, currentTopNode);
|
||||||
currentTopNode = (MultiNode *) extendedOpNode;
|
currentTopNode = (MultiNode *) extendedOpNode;
|
||||||
|
|
||||||
|
@ -1821,12 +1821,14 @@ MultiProjectNode(List *targetEntryList)
|
||||||
|
|
||||||
/* Builds the extended operator node using fields from the given query tree. */
|
/* Builds the extended operator node using fields from the given query tree. */
|
||||||
MultiExtendedOp *
|
MultiExtendedOp *
|
||||||
MultiExtendedOpNode(Query *queryTree, Query *originalQuery)
|
MultiExtendedOpNode(Query *originalQuery, Query *queryTree)
|
||||||
{
|
{
|
||||||
MultiExtendedOp *extendedOpNode = CitusMakeNode(MultiExtendedOp);
|
MultiExtendedOp *extendedOpNode = CitusMakeNode(MultiExtendedOp);
|
||||||
extendedOpNode->targetList = queryTree->targetList;
|
extendedOpNode->targetList = queryTree->targetList;
|
||||||
extendedOpNode->groupClauseList = queryTree->groupClause;
|
extendedOpNode->groupClauseList = queryTree->groupClause;
|
||||||
extendedOpNode->sortClauseList = queryTree->sortClause;
|
extendedOpNode->sortClauseList = queryTree->sortClause;
|
||||||
|
extendedOpNode->originalLimitCount = originalQuery->limitCount;
|
||||||
|
extendedOpNode->originalLimitOffset = originalQuery->limitOffset;
|
||||||
extendedOpNode->limitCount = queryTree->limitCount;
|
extendedOpNode->limitCount = queryTree->limitCount;
|
||||||
extendedOpNode->limitOffset = queryTree->limitOffset;
|
extendedOpNode->limitOffset = queryTree->limitOffset;
|
||||||
extendedOpNode->havingQual = queryTree->havingQual;
|
extendedOpNode->havingQual = queryTree->havingQual;
|
||||||
|
|
|
@ -666,8 +666,8 @@ BuildJobQuery(MultiNode *multiNode, List *dependentJobList)
|
||||||
{
|
{
|
||||||
MultiExtendedOp *extendedOp = (MultiExtendedOp *) linitial(extendedOpNodeList);
|
MultiExtendedOp *extendedOp = (MultiExtendedOp *) linitial(extendedOpNodeList);
|
||||||
|
|
||||||
limitCount = extendedOp->limitCount;
|
limitCount = extendedOp->originalLimitCount;
|
||||||
limitOffset = extendedOp->limitOffset;
|
limitOffset = extendedOp->originalLimitOffset;
|
||||||
sortClauseList = extendedOp->sortClauseList;
|
sortClauseList = extendedOp->sortClauseList;
|
||||||
havingQual = extendedOp->havingQual;
|
havingQual = extendedOp->havingQual;
|
||||||
}
|
}
|
||||||
|
@ -814,8 +814,8 @@ BuildReduceQuery(MultiExtendedOp *extendedOpNode, List *dependentJobList)
|
||||||
reduceQuery->jointree = joinTree;
|
reduceQuery->jointree = joinTree;
|
||||||
reduceQuery->sortClause = extendedOpNode->sortClauseList;
|
reduceQuery->sortClause = extendedOpNode->sortClauseList;
|
||||||
reduceQuery->groupClause = extendedOpNode->groupClauseList;
|
reduceQuery->groupClause = extendedOpNode->groupClauseList;
|
||||||
reduceQuery->limitOffset = extendedOpNode->limitOffset;
|
reduceQuery->limitOffset = extendedOpNode->originalLimitOffset;
|
||||||
reduceQuery->limitCount = extendedOpNode->limitCount;
|
reduceQuery->limitCount = extendedOpNode->originalLimitCount;
|
||||||
reduceQuery->havingQual = extendedOpNode->havingQual;
|
reduceQuery->havingQual = extendedOpNode->havingQual;
|
||||||
reduceQuery->hasAggs = contain_aggs_of_level((Node *) targetList, 0);
|
reduceQuery->hasAggs = contain_aggs_of_level((Node *) targetList, 0);
|
||||||
|
|
||||||
|
@ -1551,8 +1551,8 @@ BuildSubqueryJobQuery(MultiNode *multiNode)
|
||||||
{
|
{
|
||||||
MultiExtendedOp *extendedOp = (MultiExtendedOp *) linitial(extendedOpNodeList);
|
MultiExtendedOp *extendedOp = (MultiExtendedOp *) linitial(extendedOpNodeList);
|
||||||
|
|
||||||
limitCount = extendedOp->limitCount;
|
limitCount = extendedOp->originalLimitCount;
|
||||||
limitOffset = extendedOp->limitOffset;
|
limitOffset = extendedOp->originalLimitOffset;
|
||||||
sortClauseList = extendedOp->sortClauseList;
|
sortClauseList = extendedOp->sortClauseList;
|
||||||
havingQual = extendedOp->havingQual;
|
havingQual = extendedOp->havingQual;
|
||||||
distinctClause = extendedOp->distinctClause;
|
distinctClause = extendedOp->distinctClause;
|
||||||
|
|
|
@ -551,7 +551,7 @@ SubqueryMultiNodeTree(Query *originalQuery, Query *queryTree,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* all checks have passed, safe to create the multi plan */
|
/* all checks have passed, safe to create the multi plan */
|
||||||
multiQueryNode = MultiNodeTree(queryTree);
|
multiQueryNode = MultiNodeTree(originalQuery, queryTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert(multiQueryNode != NULL);
|
Assert(multiQueryNode != NULL);
|
||||||
|
@ -1623,7 +1623,7 @@ SubqueryPushdownMultiNodeTree(Query *originalQuery)
|
||||||
* distinguish between aggregates and expressions; and we address this later
|
* distinguish between aggregates and expressions; and we address this later
|
||||||
* in the logical optimizer.
|
* 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
|
* 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
|
* expression on the LIMIT and OFFSET clauses. Note that logical optimizer
|
||||||
* expects those clauses to be already evaluated.
|
* expects those clauses to be already evaluated.
|
||||||
*/
|
*/
|
||||||
|
extendedOpNode->originalLimitCount =
|
||||||
|
PartiallyEvaluateExpression(extendedOpNode->originalLimitCount, NULL);
|
||||||
|
extendedOpNode->originalLimitOffset =
|
||||||
|
PartiallyEvaluateExpression(extendedOpNode->originalLimitOffset, NULL);
|
||||||
extendedOpNode->limitCount =
|
extendedOpNode->limitCount =
|
||||||
PartiallyEvaluateExpression(extendedOpNode->limitCount, NULL);
|
PartiallyEvaluateExpression(extendedOpNode->limitCount, NULL);
|
||||||
extendedOpNode->limitOffset =
|
extendedOpNode->limitOffset =
|
||||||
|
|
|
@ -172,6 +172,8 @@ typedef struct MultiExtendedOp
|
||||||
List *targetList;
|
List *targetList;
|
||||||
List *groupClauseList;
|
List *groupClauseList;
|
||||||
List *sortClauseList;
|
List *sortClauseList;
|
||||||
|
Node *originalLimitCount;
|
||||||
|
Node *originalLimitOffset;
|
||||||
Node *limitCount;
|
Node *limitCount;
|
||||||
Node *limitOffset;
|
Node *limitOffset;
|
||||||
Node *havingQual;
|
Node *havingQual;
|
||||||
|
@ -219,10 +221,10 @@ extern List * pull_var_clause_default(Node *node);
|
||||||
extern bool OperatorImplementsEquality(Oid opno);
|
extern bool OperatorImplementsEquality(Oid opno);
|
||||||
extern DeferredErrorMessage * DeferErrorIfUnsupportedClause(List *clauseList);
|
extern DeferredErrorMessage * DeferErrorIfUnsupportedClause(List *clauseList);
|
||||||
extern MultiProject * MultiProjectNode(List *targetEntryList);
|
extern MultiProject * MultiProjectNode(List *targetEntryList);
|
||||||
extern MultiExtendedOp * MultiExtendedOpNode(Query *queryTree, Query *originalQuery);
|
extern MultiExtendedOp * MultiExtendedOpNode(Query *originalQuery, Query *queryTree);
|
||||||
extern DeferredErrorMessage * DeferErrorIfUnsupportedSubqueryRepartition(Query *
|
extern DeferredErrorMessage * DeferErrorIfUnsupportedSubqueryRepartition(Query *
|
||||||
subqueryTree);
|
subqueryTree);
|
||||||
extern MultiNode * MultiNodeTree(Query *queryTree);
|
extern MultiNode * MultiNodeTree(Query *originalQuery, Query *queryTree);
|
||||||
|
|
||||||
|
|
||||||
#endif /* MULTI_LOGICAL_PLANNER_H */
|
#endif /* MULTI_LOGICAL_PLANNER_H */
|
||||||
|
|
Loading…
Reference in New Issue