Move recursive planning related function to recursive_planning

pull/4358/head
Sait Talha Nisanci 2020-12-06 12:55:43 +03:00
parent 2a44029aaf
commit a34504d7bf
4 changed files with 93 additions and 93 deletions

View File

@ -75,10 +75,6 @@ typedef struct ConversionCandidates
List *localTableList; /* local or citus local table */
}ConversionCandidates;
static bool ShouldConvertLocalTableJoinsToSubqueries(Query *query, List *rangeTableList,
Oid resultRelationId,
PlannerRestrictionContext *
plannerRestrictionContext);
static bool HasConstantFilterOnUniqueColumn(FromExpr *joinTree,
RangeTblEntry *rangeTableEntry, Index
rteIndex);
@ -96,8 +92,6 @@ static RangeTableEntryDetails * GetNextRTEToConvertToSubquery(FromExpr *joinTree
conversionCandidates,
PlannerRestrictionContext *
plannerRestrictionContext);
static void GetRangeTableEntriesFromJoinTree(Node *joinNode, List *rangeTableList,
List **joinRangeTableEntries);
static void RemoveFromConversionCandidates(ConversionCandidates *conversionCandidates, Oid
relationId);
static bool AllRangeTableEntriesHaveUniqueIndex(List *rangeTableEntryDetailsList);
@ -109,32 +103,22 @@ static bool AllRangeTableEntriesHaveUniqueIndex(List *rangeTableEntryDetailsList
*/
void
RecursivelyPlanLocalTableJoins(Query *query,
RecursivePlanningContext *context)
RecursivePlanningContext *context, List* rangeTableList)
{
PlannerRestrictionContext *plannerRestrictionContext =
context->plannerRestrictionContext;
List *rangeTableList = NIL;
GetRangeTableEntriesFromJoinTree((Node *) query->jointree, query->rtable,
&rangeTableList);
Oid resultRelationId = InvalidOid;
if (IsModifyCommand(query))
{
resultRelationId = ModifyQueryResultRelationId(query);
}
if (!ShouldConvertLocalTableJoinsToSubqueries(query, rangeTableList, resultRelationId,
plannerRestrictionContext))
{
return;
}
}
ConversionCandidates *conversionCandidates =
CreateConversionCandidates(query->jointree, plannerRestrictionContext,
rangeTableList, resultRelationId);
while (ShouldConvertLocalTableJoinsToSubqueries(query, rangeTableList,
resultRelationId,
plannerRestrictionContext))
{
FromExpr *joinTree = query->jointree;
@ -156,51 +140,6 @@ RecursivelyPlanLocalTableJoins(Query *query,
}
}
/*
* GetRangeTableEntriesFromJoinTree gets the range table entries that are
* on the given join tree.
*/
static void
GetRangeTableEntriesFromJoinTree(Node *joinNode, List *rangeTableList,
List **joinRangeTableEntries)
{
if (joinNode == NULL)
{
return;
}
else if (IsA(joinNode, FromExpr))
{
FromExpr *fromExpr = (FromExpr *) joinNode;
Node *fromElement;
foreach_ptr(fromElement, fromExpr->fromlist)
{
GetRangeTableEntriesFromJoinTree(fromElement, rangeTableList,
joinRangeTableEntries);
}
}
else if (IsA(joinNode, JoinExpr))
{
JoinExpr *joinExpr = (JoinExpr *) joinNode;
GetRangeTableEntriesFromJoinTree(joinExpr->larg, rangeTableList,
joinRangeTableEntries);
GetRangeTableEntriesFromJoinTree(joinExpr->rarg, rangeTableList,
joinRangeTableEntries);
}
else if (IsA(joinNode, RangeTblRef))
{
int rangeTableIndex = ((RangeTblRef *) joinNode)->rtindex;
RangeTblEntry *rte = rt_fetch(rangeTableIndex, rangeTableList);
*joinRangeTableEntries = lappend(*joinRangeTableEntries, rte);
}
else
{
pg_unreachable();
}
}
/*
* GetNextRTEToConvertToSubquery returns the range table entry
* which should be converted to a subquery. It considers the local join policy
@ -291,9 +230,8 @@ RemoveFromConversionCandidates(ConversionCandidates *conversionCandidates, Oid r
* ShouldConvertLocalTableJoinsToSubqueries returns true if we should
* convert local-dist table joins to subqueries.
*/
static bool
bool
ShouldConvertLocalTableJoinsToSubqueries(Query *query, List *rangeTableList,
Oid resultRelationId,
PlannerRestrictionContext *
plannerRestrictionContext)
{
@ -303,7 +241,7 @@ ShouldConvertLocalTableJoinsToSubqueries(Query *query, List *rangeTableList,
return false;
}
if (!ContainsTableToBeConvertedToSubquery(rangeTableList, resultRelationId))
if (!ContainsTableToBeConvertedToSubquery(rangeTableList))
{
return false;
}

View File

@ -178,9 +178,11 @@ static Query * BuildReadIntermediateResultsQuery(List *targetEntryList,
List *columnAliasList,
Const *resultIdConst, Oid functionOid,
bool useBinaryCopyFormat);
static void UpdateVarNosInQualForSubquery(Query *query);
static bool ModifiesLocalTableWithRemoteCitusLocalTable(List *rangeTableList, Oid
resultRelationId);
static void
UpdateVarNosInNode(Query *query, Index newVarNo);
static bool ModifiesLocalTableWithRemoteCitusLocalTable(List *rangeTableList);
static void GetRangeTableEntriesFromJoinTree(Node *joinNode, List *rangeTableList,
List **joinRangeTableEntries);
/*
* GenerateSubplansForSubqueriesAndCTEs is a wrapper around RecursivelyPlanSubqueriesAndCTEs.
@ -336,18 +338,75 @@ RecursivelyPlanSubqueriesAndCTEs(Query *query, RecursivePlanningContext *context
RecursivelyPlanNonColocatedSubqueries(query, context);
}
/*
* Logical planner cannot handle "local_table" [OUTER] JOIN "dist_table", or
* a query with local table/citus local table and subquery. We convert local/citus local
* tables to a subquery until they can be planned.
* This is the last call in this function since we want the other calls to be finished
* so that we can check if the current plan is router plannable at any step within this function.
*/
RecursivelyPlanLocalTableJoins(query, context);
PlannerRestrictionContext *plannerRestrictionContext =
context->plannerRestrictionContext;
List *rangeTableList = NIL;
GetRangeTableEntriesFromJoinTree((Node *) query->jointree, query->rtable,
&rangeTableList);
if (ShouldConvertLocalTableJoinsToSubqueries(query, rangeTableList,
plannerRestrictionContext)) {
/*
* Logical planner cannot handle "local_table" [OUTER] JOIN "dist_table", or
* a query with local table/citus local table and subquery. We convert local/citus local
* tables to a subquery until they can be planned.
* This is the last call in this function since we want the other calls to be finished
* so that we can check if the current plan is router plannable at any step within this function.
*/
RecursivelyPlanLocalTableJoins(query, context, rangeTableList);
}
return NULL;
}
/*
* GetRangeTableEntriesFromJoinTree gets the range table entries that are
* on the given join tree.
*/
static void
GetRangeTableEntriesFromJoinTree(Node *joinNode, List *rangeTableList,
List **joinRangeTableEntries)
{
if (joinNode == NULL)
{
return;
}
else if (IsA(joinNode, FromExpr))
{
FromExpr *fromExpr = (FromExpr *) joinNode;
Node *fromElement;
foreach_ptr(fromElement, fromExpr->fromlist)
{
GetRangeTableEntriesFromJoinTree(fromElement, rangeTableList,
joinRangeTableEntries);
}
}
else if (IsA(joinNode, JoinExpr))
{
JoinExpr *joinExpr = (JoinExpr *) joinNode;
GetRangeTableEntriesFromJoinTree(joinExpr->larg, rangeTableList,
joinRangeTableEntries);
GetRangeTableEntriesFromJoinTree(joinExpr->rarg, rangeTableList,
joinRangeTableEntries);
}
else if (IsA(joinNode, RangeTblRef))
{
int rangeTableIndex = ((RangeTblRef *) joinNode)->rtindex;
RangeTblEntry *rte = rt_fetch(rangeTableIndex, rangeTableList);
*joinRangeTableEntries = lappend(*joinRangeTableEntries, rte);
}
else
{
pg_unreachable();
}
}
/*
* ShouldRecursivelyPlanNonColocatedSubqueries returns true if the input query contains joins
@ -1360,6 +1419,8 @@ NodeContainsSubqueryReferencingOuterQuery(Node *node)
/*
* ReplaceRTERelationWithRteSubquery replaces the input rte relation target entry
* with a subquery. The function also pushes down the filters to the subquery.
*
* It then recursively plans the subquery.
*/
void
ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry, List *restrictionList,
@ -1369,10 +1430,7 @@ ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry, List *restrict
Query *subquery = WrapRteRelationIntoSubquery(rangeTableEntry, requiredAttrNumbers);
Expr *andedBoundExpressions = make_ands_explicit(restrictionList);
subquery->jointree->quals = (Node *) andedBoundExpressions;
UpdateVarNosInQualForSubquery(subquery);
/* force recursively planning of the newly created subquery */
subquery->limitOffset = (Node *) MakeIntegerConst(0);
UpdateVarNosInNode(subquery, SINGLE_RTE_INDEX);
/* replace the function with the constructed subquery */
rangeTableEntry->rtekind = RTE_SUBQUERY;
@ -1396,24 +1454,25 @@ ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry, List *restrict
get_rel_name(rangeTableEntry->relid),
ApplyLogRedaction(subqueryString->data))));
}
/* as we created the subquery, now forcefully recursively plan it */
RecursivelyPlanSubquery(rangeTableEntry->subquery, context);
}
/*
* UpdateVarNosInQualForSubquery iterates the Vars in the
* given quals node and updates the varno's as 1 as there
* will be only one RTE in rtable, which is the subquery.
* UpdateVarNosInNode iterates the Vars in the
* given node and updates the varno's as the newVarNo.
*/
static void
UpdateVarNosInQualForSubquery(Query *query)
UpdateVarNosInNode(Query *query, Index newVarNo)
{
List *varList = pull_var_clause(query->jointree->quals, PVC_RECURSE_AGGREGATES |
PVC_RECURSE_PLACEHOLDERS);
Var *var = NULL;
foreach_ptr(var, varList)
{
var->varno = SINGLE_RTE_INDEX;
var->varno = newVarNo;
}
}
@ -1423,13 +1482,13 @@ UpdateVarNosInQualForSubquery(Query *query)
* any table that should be converted to a subquery, which otherwise is not plannable.
*/
bool
ContainsTableToBeConvertedToSubquery(List *rangeTableList, Oid resultRelationId)
ContainsTableToBeConvertedToSubquery(List *rangeTableList)
{
if (ContainsLocalTableDistributedTableJoin(rangeTableList))
{
return true;
}
if (ModifiesLocalTableWithRemoteCitusLocalTable(rangeTableList, resultRelationId))
if (ModifiesLocalTableWithRemoteCitusLocalTable(rangeTableList))
{
return true;
}
@ -1443,7 +1502,7 @@ ContainsTableToBeConvertedToSubquery(List *rangeTableList, Oid resultRelationId)
* MX structure.
*/
static bool
ModifiesLocalTableWithRemoteCitusLocalTable(List *rangeTableList, Oid resultRelationId)
ModifiesLocalTableWithRemoteCitusLocalTable(List *rangeTableList)
{
bool containsLocalResultRelation = false;
bool containsRemoteCitusLocalTable = false;

View File

@ -27,7 +27,11 @@ typedef enum
extern int LocalTableJoinPolicy;
extern bool
ShouldConvertLocalTableJoinsToSubqueries(Query *query,
List *rangeTableList,
PlannerRestrictionContext *plannerRestrictionContext);
extern void RecursivelyPlanLocalTableJoins(Query *query,
RecursivePlanningContext *context);
RecursivePlanningContext *context, List *rangeTableList);
#endif /* LOCAL_DISTRIBUTED_JOIN_PLANNER_H */

View File

@ -53,8 +53,7 @@ extern void ReplaceRTERelationWithRteSubquery(RangeTblEntry *rangeTableEntry,
List *restrictionList,
List *requiredAttrNumbers,
RecursivePlanningContext *context);
extern bool ContainsTableToBeConvertedToSubquery(List *rangeTableList, Oid
resultRelationId);
extern bool ContainsTableToBeConvertedToSubquery(List *rangeTableList);
extern bool IsRecursivelyPlannableRelation(RangeTblEntry *rangeTableEntry);
extern bool IsRelationLocalTableOrMatView(Oid relationId);
#endif /* RECURSIVE_PLANNING_H */