diff --git a/src/backend/distributed/planner/multi_colocated_subquery_planner.c b/src/backend/distributed/planner/multi_colocated_subquery_planner.c index 16da950d2..672fa0100 100644 --- a/src/backend/distributed/planner/multi_colocated_subquery_planner.c +++ b/src/backend/distributed/planner/multi_colocated_subquery_planner.c @@ -32,7 +32,7 @@ static uint32 attributeEquivalenceId = 1; * relation attributes (i.e., not random expressions), we create an * AttributeEquivalenceClass to record this knowledge. If we later find another * equivalence B = C, we create another AttributeEquivalenceClass. Finally, we can - * apply transitity rules and generate a new AttributeEquivalenceClass which includes + * apply transitivity rules and generate a new AttributeEquivalenceClass which includes * A, B and C. * * Note that equality among the members are identified by the varattno and rteIdentity. @@ -45,20 +45,20 @@ typedef struct AttributeEquivalenceClass /* * AttributeEquivalenceClassMember - one member expression of an - * AttributeEquivalenceClassMember. The important thing to consider is that + * AttributeEquivalenceClass. The important thing to consider is that * the class member contains "rteIndentity" field. Note that each RTE_RELATION * is assigned a unique rteIdentity in AssignRTEIdentities() function. * - * "varno" and "varattrno" is directly used from a Var clause that is being added + * "varno" and "varattno" is directly used from a Var clause that is being added * to the attribute equivalence. Since we only use this class for relations, the member * also includes the relation id field. */ typedef struct AttributeEquivalenceClassMember { + Oid relationId; + int rteIdentity; Index varno; AttrNumber varattno; - Oid relationId; - int rteIdendity; } AttributeEquivalenceClassMember; @@ -67,9 +67,9 @@ static List * GenerateAttributeEquivalencesForRelationRestrictions( RelationRestrictionContext *restrictionContext); static AttributeEquivalenceClass * AttributeEquivalenceClassForEquivalenceClass( EquivalenceClass *plannerEqClass, RelationRestriction *relationRestriction); -static void AddToAttributeEquivalenceClass(PlannerInfo *root, Var *varToBeAdded, - AttributeEquivalenceClass ** - attributeEquivalanceClass); +static void AddToAttributeEquivalenceClass(AttributeEquivalenceClass ** + attributeEquivalanceClass, + PlannerInfo *root, Var *varToBeAdded); static Var * GetVarFromAssignedParam(List *parentPlannerParamList, Param *plannerParam); static List * GenerateAttributeEquivalencesForJoinRestrictions(JoinRestrictionContext @@ -78,9 +78,9 @@ static bool AttributeClassContainsAttributeClassMember(AttributeEquivalenceClass inputMember, AttributeEquivalenceClass * attributeEquivalenceClass); -static List * AddAttributeClassToAttributeClassList(AttributeEquivalenceClass * - attributeEquivalance, - List *attributeEquivalenceList); +static List * AddAttributeClassToAttributeClassList(List *attributeEquivalenceList, + AttributeEquivalenceClass * + attributeEquivalance); static AttributeEquivalenceClass * GenerateCommonEquivalence(List * attributeEquivalenceList); static void ListConcatUniqueAttributeClassMemberLists(AttributeEquivalenceClass ** @@ -94,6 +94,12 @@ static void ListConcatUniqueAttributeClassMemberLists(AttributeEquivalenceClass * RTE_RELATION follows the above rule, we can conclude that all RTE_RELATIONs are * joined on their partition keys. * + * The function returns true if all relations are joined on their partition keys. + * Otherwise, the function returns false. Since reference tables do not have partition + * keys, we skip processing them. Also, if the query includes only a single non-reference + * distributed relation, the function returns true since it doesn't make sense to check + * for partition key equality in that case. + * * In order to do that, we invented a new equivalence class namely: * AttributeEquivalenceClass. In very simple words, a AttributeEquivalenceClass is * identified by an unique id and consists of a list of AttributeEquivalenceMembers. @@ -112,14 +118,15 @@ static void ListConcatUniqueAttributeClassMemberLists(AttributeEquivalenceClass * to find as much as information that Postgres planner provides to extensions. For the * details of the usage, please see GenerateAttributeEquivalencesForRelationRestrictions() * and GenerateAttributeEquivalencesForJoinRestrictions() - * - * Finally, as the name of the function reveals, the function returns true if all relations - * are joined on their partition keys. Otherwise, the function returns false. */ bool -AllRelationsJoinedOnPartitionKey(RelationRestrictionContext *restrictionContext, - JoinRestrictionContext *joinRestrictionContext) +AllRelationsJoinedOnPartitionKey(PlannerRestrictionContext *plannerRestrictionContext) { + RelationRestrictionContext *restrictionContext = + plannerRestrictionContext->relationRestrictionContext; + JoinRestrictionContext *joinRestrictionContext = + plannerRestrictionContext->joinRestrictionContext; + List *relationRestrictionAttributeEquivalenceList = NIL; List *joinRestrictionAttributeEquivalenceList = NIL; List *allAttributeEquivalenceList = NIL; @@ -127,7 +134,6 @@ AllRelationsJoinedOnPartitionKey(RelationRestrictionContext *restrictionContext, uint32 referenceRelationCount = ReferenceRelationCount(restrictionContext); uint32 totalRelationCount = list_length(restrictionContext->relationRestrictionList); uint32 nonReferenceRelationCount = totalRelationCount - referenceRelationCount; - ListCell *commonEqClassCell = NULL; ListCell *relationRestrictionCell = NULL; Relids commonRteIdentities = NULL; @@ -170,8 +176,9 @@ AllRelationsJoinedOnPartitionKey(RelationRestrictionContext *restrictionContext, /* add the rte indexes of relations to a bitmap */ foreach(commonEqClassCell, commonEquivalenceClass->equivalentAttributes) { - AttributeEquivalenceClassMember *classMember = lfirst(commonEqClassCell); - int rteIdentity = classMember->rteIdendity; + AttributeEquivalenceClassMember *classMember = + (AttributeEquivalenceClassMember *) lfirst(commonEqClassCell); + int rteIdentity = classMember->rteIdentity; commonRteIdentities = bms_add_member(commonRteIdentities, rteIdentity); } @@ -179,7 +186,8 @@ AllRelationsJoinedOnPartitionKey(RelationRestrictionContext *restrictionContext, /* check whether all relations exists in the main restriction list */ foreach(relationRestrictionCell, restrictionContext->relationRestrictionList) { - RelationRestriction *relationRestriction = lfirst(relationRestrictionCell); + RelationRestriction *relationRestriction = + (RelationRestriction *) lfirst(relationRestrictionCell); int rteIdentity = GetRTEIdentity(relationRestriction->rte); if (PartitionKey(relationRestriction->relationId) && @@ -205,7 +213,8 @@ ReferenceRelationCount(RelationRestrictionContext *restrictionContext) foreach(relationRestrictionCell, restrictionContext->relationRestrictionList) { - RelationRestriction *relationRestriction = lfirst(relationRestrictionCell); + RelationRestriction *relationRestriction = + (RelationRestriction *) lfirst(relationRestrictionCell); if (PartitionMethod(relationRestriction->relationId) == DISTRIBUTE_BY_NONE) { @@ -243,21 +252,23 @@ GenerateAttributeEquivalencesForRelationRestrictions(RelationRestrictionContext foreach(relationRestrictionCell, restrictionContext->relationRestrictionList) { - RelationRestriction *relationRestriction = lfirst(relationRestrictionCell); + RelationRestriction *relationRestriction = + (RelationRestriction *) lfirst(relationRestrictionCell); List *equivalenceClasses = relationRestriction->plannerInfo->eq_classes; - ListCell *equivilanceClassCell = NULL; + ListCell *equivalenceClassCell = NULL; - foreach(equivilanceClassCell, equivalenceClasses) + foreach(equivalenceClassCell, equivalenceClasses) { - EquivalenceClass *plannerEqClass = lfirst(equivilanceClassCell); + EquivalenceClass *plannerEqClass = + (EquivalenceClass *) lfirst(equivalenceClassCell); AttributeEquivalenceClass *attributeEquivalance = AttributeEquivalenceClassForEquivalenceClass(plannerEqClass, relationRestriction); attributeEquivalenceList = - AddAttributeClassToAttributeClassList(attributeEquivalance, - attributeEquivalenceList); + AddAttributeClassToAttributeClassList(attributeEquivalenceList, + attributeEquivalance); } } @@ -288,7 +299,8 @@ AttributeEquivalenceClassForEquivalenceClass(EquivalenceClass *plannerEqClass, foreach(equivilanceMemberCell, plannerEqClass->ec_members) { - EquivalenceMember *equivalenceMember = lfirst(equivilanceMemberCell); + EquivalenceMember *equivalenceMember = + (EquivalenceMember *) lfirst(equivilanceMemberCell); Node *equivalenceNode = strip_implicit_coercions( (Node *) equivalenceMember->em_expr); Expr *strippedEquivalenceExpr = (Expr *) equivalenceNode; @@ -304,17 +316,16 @@ AttributeEquivalenceClassForEquivalenceClass(EquivalenceClass *plannerEqClass, equivalenceParam); if (expressionVar) { - AddToAttributeEquivalenceClass( - relationRestriction->parentPlannerInfo, - expressionVar, - &attributeEquivalance); + AddToAttributeEquivalenceClass(&attributeEquivalance, + relationRestriction->parentPlannerInfo, + expressionVar); } } else if (IsA(strippedEquivalenceExpr, Var)) { expressionVar = (Var *) strippedEquivalenceExpr; - AddToAttributeEquivalenceClass(plannerInfo, expressionVar, - &attributeEquivalance); + AddToAttributeEquivalenceClass(&attributeEquivalance, plannerInfo, + expressionVar); } } @@ -368,7 +379,8 @@ GetVarFromAssignedParam(List *parentPlannerParamList, Param *plannerParam) foreach(plannerParameterCell, parentPlannerParamList) { - PlannerParamItem *plannerParamItem = lfirst(plannerParameterCell); + PlannerParamItem *plannerParamItem = + (PlannerParamItem *) lfirst(plannerParameterCell); if (plannerParamItem->paramId != plannerParam->paramid) { @@ -498,7 +510,8 @@ ListConcatUniqueAttributeClassMemberLists(AttributeEquivalenceClass **firstClass foreach(equivalenceClassMemberCell, equivalenceMemberList) { - AttributeEquivalenceClassMember *newEqMember = lfirst(equivalenceClassMemberCell); + AttributeEquivalenceClassMember *newEqMember = + (AttributeEquivalenceClassMember *) lfirst(equivalenceClassMemberCell); if (AttributeClassContainsAttributeClassMember(newEqMember, *firstClass)) { @@ -532,7 +545,8 @@ GenerateAttributeEquivalencesForJoinRestrictions(JoinRestrictionContext * foreach(joinRestrictionCell, joinRestrictionContext->joinRestrictionList) { - JoinRestriction *joinRestriction = lfirst(joinRestrictionCell); + JoinRestriction *joinRestriction = + (JoinRestriction *) lfirst(joinRestrictionCell); ListCell *restrictionInfoList = NULL; foreach(restrictionInfoList, joinRestriction->joinRestrictInfoList) @@ -581,14 +595,15 @@ GenerateAttributeEquivalencesForJoinRestrictions(JoinRestrictionContext * attributeEquivalance = palloc0(sizeof(AttributeEquivalenceClass)); attributeEquivalance->equivalenceId = attributeEquivalenceId++; - AddToAttributeEquivalenceClass(joinRestriction->plannerInfo, leftVar, - &attributeEquivalance); - AddToAttributeEquivalenceClass(joinRestriction->plannerInfo, rightVar, - &attributeEquivalance); + AddToAttributeEquivalenceClass(&attributeEquivalance, + joinRestriction->plannerInfo, leftVar); + + AddToAttributeEquivalenceClass(&attributeEquivalance, + joinRestriction->plannerInfo, rightVar); attributeEquivalenceList = - AddAttributeClassToAttributeClassList(attributeEquivalance, - attributeEquivalenceList); + AddAttributeClassToAttributeClassList(attributeEquivalenceList, + attributeEquivalance); } } @@ -624,8 +639,8 @@ GenerateAttributeEquivalencesForJoinRestrictions(JoinRestrictionContext * * This implies that there wouldn't be any columns for reference tables. */ static void -AddToAttributeEquivalenceClass(PlannerInfo *root, Var *varToBeAdded, - AttributeEquivalenceClass **attributeEquivalanceClass) +AddToAttributeEquivalenceClass(AttributeEquivalenceClass **attributeEquivalanceClass, + PlannerInfo *root, Var *varToBeAdded) { RangeTblEntry *rangeTableEntry = root->simple_rte_array[varToBeAdded->varno]; @@ -650,7 +665,7 @@ AddToAttributeEquivalenceClass(PlannerInfo *root, Var *varToBeAdded, attributeEqMember->varattno = varToBeAdded->varattno; attributeEqMember->varno = varToBeAdded->varno; - attributeEqMember->rteIdendity = GetRTEIdentity(rangeTableEntry); + attributeEqMember->rteIdentity = GetRTEIdentity(rangeTableEntry); attributeEqMember->relationId = rangeTableEntry->relid; (*attributeEquivalanceClass)->equivalentAttributes = @@ -669,6 +684,12 @@ AddToAttributeEquivalenceClass(PlannerInfo *root, Var *varToBeAdded, return; } + /* we also don't want to process ctid, tableoid etc */ + if (varToBeAdded->varattno < InvalidAttrNumber) + { + return; + } + baseRelOptInfo = find_base_rel(root, varToBeAdded->varno); /* If the subquery hasn't been planned yet, we have to punt */ @@ -710,17 +731,17 @@ AddToAttributeEquivalenceClass(PlannerInfo *root, Var *varToBeAdded, RangeTblRef *rightRangeTableReference = (RangeTblRef *) unionStatement->rarg; varToBeAdded->varno = leftRangeTableReference->rtindex; - AddToAttributeEquivalenceClass(baseRelOptInfo->subroot, varToBeAdded, - attributeEquivalanceClass); + AddToAttributeEquivalenceClass(attributeEquivalanceClass, + baseRelOptInfo->subroot, varToBeAdded); varToBeAdded->varno = rightRangeTableReference->rtindex; - AddToAttributeEquivalenceClass(baseRelOptInfo->subroot, varToBeAdded, - attributeEquivalanceClass); + AddToAttributeEquivalenceClass(attributeEquivalanceClass, + baseRelOptInfo->subroot, varToBeAdded); } else if (varToBeAdded && IsA(varToBeAdded, Var) && varToBeAdded->varlevelsup == 0) { - AddToAttributeEquivalenceClass(baseRelOptInfo->subroot, varToBeAdded, - attributeEquivalanceClass); + AddToAttributeEquivalenceClass(attributeEquivalanceClass, + baseRelOptInfo->subroot, varToBeAdded); } } } @@ -739,8 +760,9 @@ AttributeClassContainsAttributeClassMember(AttributeEquivalenceClassMember *inpu ListCell *classCell = NULL; foreach(classCell, attributeEquivalenceClass->equivalentAttributes) { - AttributeEquivalenceClassMember *memberOfClass = lfirst(classCell); - if (memberOfClass->rteIdendity == inputMember->rteIdendity && + AttributeEquivalenceClassMember *memberOfClass = + (AttributeEquivalenceClassMember *) lfirst(classCell); + if (memberOfClass->rteIdentity == inputMember->rteIdentity && memberOfClass->varattno == inputMember->varattno) { return true; @@ -760,8 +782,8 @@ AttributeClassContainsAttributeClassMember(AttributeEquivalenceClassMember *inpu * not contribute to our purposes, we skip such classed adding to the list. */ static List * -AddAttributeClassToAttributeClassList(AttributeEquivalenceClass *attributeEquivalance, - List *attributeEquivalenceList) +AddAttributeClassToAttributeClassList(List *attributeEquivalenceList, + AttributeEquivalenceClass *attributeEquivalance) { List *equivalentAttributes = NULL; diff --git a/src/backend/distributed/planner/multi_planner.c b/src/backend/distributed/planner/multi_planner.c index 0ba89afce..af23d9a48 100644 --- a/src/backend/distributed/planner/multi_planner.c +++ b/src/backend/distributed/planner/multi_planner.c @@ -32,8 +32,7 @@ #include "utils/memutils.h" -static List *relationRestrictionContextList = NIL; -static List *joinRestrictionContextList = NIL; +static List *plannerRestrictionContextList = NIL; /* create custom scan methods for separate executors */ static CustomScanMethods RealTimeCustomScanMethods = { @@ -60,8 +59,8 @@ static CustomScanMethods DelayedErrorCustomScanMethods = { /* local function forward declarations */ static PlannedStmt * CreateDistributedPlan(PlannedStmt *localPlan, Query *originalQuery, Query *query, ParamListInfo boundParams, - RelationRestrictionContext *restrictionContext, - JoinRestrictionContext *joinRestrictionContext); + PlannerRestrictionContext * + plannerRestrictionContext); static void AssignRTEIdentities(Query *queryTree); static void AssignRTEIdentity(RangeTblEntry *rangeTableEntry, int rteIdentifier); static Node * SerializeMultiPlan(struct MultiPlan *multiPlan); @@ -72,10 +71,10 @@ static PlannedStmt * FinalizeNonRouterPlan(PlannedStmt *localPlan, MultiPlan *mu static PlannedStmt * FinalizeRouterPlan(PlannedStmt *localPlan, CustomScan *customScan); static void CheckNodeIsDumpable(Node *node); static List * CopyPlanParamList(List *originalPlanParamList); -static void CreateAndPushPlannerContexts(void); -static RelationRestrictionContext * CurrentRestrictionContext(void); +static PlannerRestrictionContext * CreateAndPushPlannerRestrictionContext(void); +static RelationRestrictionContext * CurrentRelationRestrictionContext(void); static JoinRestrictionContext * CurrentJoinRestrictionContext(void); -static void PopRestrictionContexts(void); +static void PopPlannerRestrictionContext(void); static bool HasUnresolvedExternParamsWalker(Node *expression, ParamListInfo boundParams); @@ -86,8 +85,7 @@ multi_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) PlannedStmt *result = NULL; bool needsDistributedPlanning = NeedsDistributedPlanning(parse); Query *originalQuery = NULL; - RelationRestrictionContext *relationRestrictionContext = NULL; - JoinRestrictionContext *joinRestrictionContext = NULL; + PlannerRestrictionContext *plannerRestrictionContext = NULL; /* * standard_planner scribbles on it's input, but for deparsing we need the @@ -101,10 +99,7 @@ multi_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) } /* create a restriction context and put it at the end if context list */ - CreateAndPushPlannerContexts(); - - relationRestrictionContext = CurrentRestrictionContext(); - joinRestrictionContext = CurrentJoinRestrictionContext(); + plannerRestrictionContext = CreateAndPushPlannerRestrictionContext(); PG_TRY(); { @@ -118,19 +113,18 @@ multi_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) if (needsDistributedPlanning) { result = CreateDistributedPlan(result, originalQuery, parse, - boundParams, relationRestrictionContext, - joinRestrictionContext); + boundParams, plannerRestrictionContext); } } PG_CATCH(); { - PopRestrictionContexts(); + PopPlannerRestrictionContext(); PG_RE_THROW(); } PG_END_TRY(); /* remove the context from the context list */ - PopRestrictionContexts(); + PopPlannerRestrictionContext(); return result; } @@ -187,6 +181,18 @@ AssignRTEIdentity(RangeTblEntry *rangeTableEntry, int rteIdentifier) } +/* GetRTEIdentity returns the identity assigned with AssignRTEIdentity. */ +int +GetRTEIdentity(RangeTblEntry *rte) +{ + Assert(rte->rtekind == RTE_RELATION); + Assert(IsA(rte->values_lists, IntList)); + Assert(list_length(rte->values_lists) == 1); + + return linitial_int(rte->values_lists); +} + + /* * IsModifyCommand returns true if the query performs modifications, false * otherwise. @@ -232,8 +238,7 @@ IsModifyMultiPlan(MultiPlan *multiPlan) static PlannedStmt * CreateDistributedPlan(PlannedStmt *localPlan, Query *originalQuery, Query *query, ParamListInfo boundParams, - RelationRestrictionContext *restrictionContext, - JoinRestrictionContext *joinRestrictionContext) + PlannerRestrictionContext *plannerRestrictionContext) { MultiPlan *distributedPlan = NULL; PlannedStmt *resultPlan = NULL; @@ -247,8 +252,8 @@ CreateDistributedPlan(PlannedStmt *localPlan, Query *originalQuery, Query *query if (IsModifyCommand(query)) { /* modifications are always routed through the same planner/executor */ - distributedPlan = CreateModifyPlan(originalQuery, query, restrictionContext, - joinRestrictionContext); + distributedPlan = + CreateModifyPlan(originalQuery, query, plannerRestrictionContext); Assert(distributedPlan); } @@ -262,7 +267,11 @@ CreateDistributedPlan(PlannedStmt *localPlan, Query *originalQuery, Query *query */ if (EnableRouterExecution) { - distributedPlan = CreateRouterPlan(originalQuery, query, restrictionContext); + RelationRestrictionContext *relationRestrictionContext = + plannerRestrictionContext->relationRestrictionContext; + + distributedPlan = CreateRouterPlan(originalQuery, query, + relationRestrictionContext); /* for debugging it's useful to display why query was not router plannable */ if (distributedPlan && distributedPlan->planningError) @@ -639,7 +648,6 @@ multi_join_restriction_hook(PlannerInfo *root, joinRestriction->joinRestrictInfoList = restrictInfoList; joinRestriction->plannerInfo = root; - joinContext->joinRestrictionList = lappend(joinContext->joinRestrictionList, joinRestriction); } @@ -668,7 +676,7 @@ multi_relation_restriction_hook(PlannerInfo *root, RelOptInfo *relOptInfo, Index distributedTable = IsDistributedTable(rte->relid); localTable = !distributedTable; - restrictionContext = CurrentRestrictionContext(); + restrictionContext = CurrentRelationRestrictionContext(); Assert(restrictionContext != NULL); relationRestriction = palloc0(sizeof(RelationRestriction)); @@ -708,18 +716,6 @@ multi_relation_restriction_hook(PlannerInfo *root, RelOptInfo *relOptInfo, Index } -/* GetRTEIdentity returns the identity assigned with AssignRTEIdentity. */ -int -GetRTEIdentity(RangeTblEntry *rte) -{ - Assert(rte->rtekind == RTE_RELATION); - Assert(IsA(rte->values_lists, IntList)); - Assert(list_length(rte->values_lists) == 1); - - return linitial_int(rte->values_lists); -} - - /* * CopyPlanParamList deep copies the input PlannerParamItem list and returns the newly * allocated list. @@ -748,43 +744,50 @@ CopyPlanParamList(List *originalPlanParamList) /* - * CreateAndPushPlannerContextes creates a new restriction context and a new join context, - * inserts it to the beginning of the respective context lists. + * CreateAndPushPlannerRestrictionContext creates a new relation restriction context + * and a new join context, inserts it to the beginning of the + * plannerRestrictionContextList. */ -static void -CreateAndPushPlannerContexts(void) +static PlannerRestrictionContext * +CreateAndPushPlannerRestrictionContext(void) { - RelationRestrictionContext *restrictionContext = + PlannerRestrictionContext *plannerRestrictionContext = + palloc0(sizeof(PlannerRestrictionContext)); + + plannerRestrictionContext->relationRestrictionContext = palloc0(sizeof(RelationRestrictionContext)); - JoinRestrictionContext *joinContext = + plannerRestrictionContext->joinRestrictionContext = palloc0(sizeof(JoinRestrictionContext)); /* we'll apply logical AND as we add tables */ - restrictionContext->allReferenceTables = true; + plannerRestrictionContext->relationRestrictionContext->allReferenceTables = true; - relationRestrictionContextList = lcons(restrictionContext, - relationRestrictionContextList); - joinRestrictionContextList = lcons(joinContext, - joinRestrictionContextList); + plannerRestrictionContextList = lcons(plannerRestrictionContext, + plannerRestrictionContextList); + + return plannerRestrictionContext; } /* * CurrentRestrictionContext returns the the last restriction context from the - * list. + * relationRestrictionContext list. */ static RelationRestrictionContext * -CurrentRestrictionContext(void) +CurrentRelationRestrictionContext(void) { - RelationRestrictionContext *restrictionContext = NULL; + PlannerRestrictionContext *plannerRestrictionContext = NULL; + RelationRestrictionContext *relationRestrictionContext = NULL; - Assert(relationRestrictionContextList != NIL); + Assert(plannerRestrictionContextList != NIL); - restrictionContext = - (RelationRestrictionContext *) linitial(relationRestrictionContextList); + plannerRestrictionContext = + (PlannerRestrictionContext *) linitial(plannerRestrictionContextList); - return restrictionContext; + relationRestrictionContext = plannerRestrictionContext->relationRestrictionContext; + + return relationRestrictionContext; } @@ -795,25 +798,28 @@ CurrentRestrictionContext(void) static JoinRestrictionContext * CurrentJoinRestrictionContext(void) { - JoinRestrictionContext *joinContext = NULL; + PlannerRestrictionContext *plannerRestrictionContext = NULL; + JoinRestrictionContext *joinRestrictionContext = NULL; - Assert(joinRestrictionContextList != NIL); + Assert(plannerRestrictionContextList != NIL); - joinContext = (JoinRestrictionContext *) linitial(joinRestrictionContextList); + plannerRestrictionContext = + (PlannerRestrictionContext *) linitial(plannerRestrictionContextList); - return joinContext; + joinRestrictionContext = plannerRestrictionContext->joinRestrictionContext; + + return joinRestrictionContext; } /* - * PopRestrictionContexts removes the most recently added restriction contexts from - * the restriction and join context lists. The function assumes the lists are not empty. + * PopPlannerRestrictionContext removes the most recently added restriction contexts from + * the planner restriction context list. The function assumes the list is not empty. */ static void -PopRestrictionContexts(void) +PopPlannerRestrictionContext(void) { - relationRestrictionContextList = list_delete_first(relationRestrictionContextList); - joinRestrictionContextList = list_delete_first(joinRestrictionContextList); + plannerRestrictionContextList = list_delete_first(plannerRestrictionContextList); } diff --git a/src/backend/distributed/planner/multi_router_planner.c b/src/backend/distributed/planner/multi_router_planner.c index 76f3cd249..c070c0591 100644 --- a/src/backend/distributed/planner/multi_router_planner.c +++ b/src/backend/distributed/planner/multi_router_planner.c @@ -85,11 +85,8 @@ static MultiPlan * CreateSingleTaskRouterPlan(Query *originalQuery, RelationRestrictionContext * restrictionContext); static MultiPlan * CreateInsertSelectRouterPlan(Query *originalQuery, - RelationRestrictionContext * - restrictionContext, - JoinRestrictionContext * - joinRestrictionContext); - + PlannerRestrictionContext * + plannerRestrictionContext); static Task * RouterModifyTaskForShardInterval(Query *originalQuery, ShardInterval *shardInterval, RelationRestrictionContext * @@ -171,18 +168,19 @@ CreateRouterPlan(Query *originalQuery, Query *query, */ MultiPlan * CreateModifyPlan(Query *originalQuery, Query *query, - RelationRestrictionContext *restrictionContext, - JoinRestrictionContext *joinRestrictionContext) + PlannerRestrictionContext *plannerRestrictionContext) { if (InsertSelectQuery(originalQuery)) { - return CreateInsertSelectRouterPlan(originalQuery, restrictionContext, - joinRestrictionContext); + return CreateInsertSelectRouterPlan(originalQuery, plannerRestrictionContext); } else { + RelationRestrictionContext *relationRestrictionContext = + plannerRestrictionContext->relationRestrictionContext; + return CreateSingleTaskRouterPlan(originalQuery, query, - restrictionContext); + relationRestrictionContext); } } @@ -266,8 +264,7 @@ CreateSingleTaskRouterPlan(Query *originalQuery, Query *query, */ static MultiPlan * CreateInsertSelectRouterPlan(Query *originalQuery, - RelationRestrictionContext *restrictionContext, - JoinRestrictionContext *joinRestrictionContext) + PlannerRestrictionContext *plannerRestrictionContext) { int shardOffset = 0; List *sqlTaskList = NIL; @@ -280,7 +277,9 @@ CreateInsertSelectRouterPlan(Query *originalQuery, Oid targetRelationId = insertRte->relid; DistTableCacheEntry *targetCacheEntry = DistributedTableCacheEntry(targetRelationId); int shardCount = targetCacheEntry->shardIntervalArrayLength; - bool allReferenceTables = restrictionContext->allReferenceTables; + RelationRestrictionContext *relationRestrictionContext = + plannerRestrictionContext->relationRestrictionContext; + bool allReferenceTables = relationRestrictionContext->allReferenceTables; bool allRelationsJoinedOnPartitionKey = false; multiPlan->operation = originalQuery->commandType; @@ -298,7 +297,7 @@ CreateInsertSelectRouterPlan(Query *originalQuery, } allRelationsJoinedOnPartitionKey = - AllRelationsJoinedOnPartitionKey(restrictionContext, joinRestrictionContext); + AllRelationsJoinedOnPartitionKey(plannerRestrictionContext); /* * Plan select query for each shard in the target table. Do so by replacing the @@ -316,7 +315,8 @@ CreateInsertSelectRouterPlan(Query *originalQuery, Task *modifyTask = NULL; modifyTask = RouterModifyTaskForShardInterval(originalQuery, targetShardInterval, - restrictionContext, taskIdIndex, + relationRestrictionContext, + taskIdIndex, allRelationsJoinedOnPartitionKey); /* add the task if it could be created */ diff --git a/src/include/distributed/multi_colocated_subquery_planner.h b/src/include/distributed/multi_colocated_subquery_planner.h index 4ec24d5d5..28f80426a 100644 --- a/src/include/distributed/multi_colocated_subquery_planner.h +++ b/src/include/distributed/multi_colocated_subquery_planner.h @@ -15,10 +15,8 @@ #include "distributed/multi_planner.h" -extern bool AllRelationsJoinedOnPartitionKey(RelationRestrictionContext * - restrictionContext, - JoinRestrictionContext * - joinRestrictionContext); +extern bool AllRelationsJoinedOnPartitionKey(PlannerRestrictionContext * + plannerRestrictionContext); #endif /* MULTI_COLOCATED_SUBQUERY_PLANNER_H */ diff --git a/src/include/distributed/multi_planner.h b/src/include/distributed/multi_planner.h index abf545d93..bf65daa63 100644 --- a/src/include/distributed/multi_planner.h +++ b/src/include/distributed/multi_planner.h @@ -54,6 +54,12 @@ typedef struct JoinRestriction PlannerInfo *plannerInfo; } JoinRestriction; +typedef struct PlannerRestrictionContext +{ + RelationRestrictionContext *relationRestrictionContext; + JoinRestrictionContext *joinRestrictionContext; +} PlannerRestrictionContext; + typedef struct RelationShard { CitusNode type; diff --git a/src/include/distributed/multi_router_planner.h b/src/include/distributed/multi_router_planner.h index 61f2c074b..91c4c963f 100644 --- a/src/include/distributed/multi_router_planner.h +++ b/src/include/distributed/multi_router_planner.h @@ -29,8 +29,8 @@ extern bool EnableRouterExecution; extern MultiPlan * CreateRouterPlan(Query *originalQuery, Query *query, RelationRestrictionContext *restrictionContext); extern MultiPlan * CreateModifyPlan(Query *originalQuery, Query *query, - RelationRestrictionContext *restrictionContext, - JoinRestrictionContext *joinRestrictionContext); + PlannerRestrictionContext * + plannerRestrictionContext); extern DeferredErrorMessage * ModifyQuerySupported(Query *queryTree); extern Query * ReorderInsertSelectTargetLists(Query *originalQuery,