Apply @mtuncer's reviews

pull/1282/head
Onder Kalaci 2017-04-03 13:32:55 +03:00
parent 427af34719
commit 4c41096370
6 changed files with 172 additions and 140 deletions

View File

@ -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;

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -54,6 +54,12 @@ typedef struct JoinRestriction
PlannerInfo *plannerInfo;
} JoinRestriction;
typedef struct PlannerRestrictionContext
{
RelationRestrictionContext *relationRestrictionContext;
JoinRestrictionContext *joinRestrictionContext;
} PlannerRestrictionContext;
typedef struct RelationShard
{
CitusNode type;

View File

@ -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,