mirror of https://github.com/citusdata/citus.git
Merge pull request #4264 from citusdata/remove_remove_duplicate
Remove RemoveDuplicateJoinRestrictions() functionpull/4267/head
commit
808f30c1a2
|
@ -615,8 +615,6 @@ CreateDistributedPlannedStmt(DistributedPlanningContext *planContext)
|
|||
{
|
||||
uint64 planId = NextPlanId++;
|
||||
bool hasUnresolvedParams = false;
|
||||
JoinRestrictionContext *joinRestrictionContext =
|
||||
planContext->plannerRestrictionContext->joinRestrictionContext;
|
||||
|
||||
PlannedStmt *resultPlan = NULL;
|
||||
|
||||
|
@ -646,9 +644,6 @@ CreateDistributedPlannedStmt(DistributedPlanningContext *planContext)
|
|||
hasUnresolvedParams = true;
|
||||
}
|
||||
|
||||
planContext->plannerRestrictionContext->joinRestrictionContext =
|
||||
RemoveDuplicateJoinRestrictions(joinRestrictionContext);
|
||||
|
||||
DistributedPlan *distributedPlan =
|
||||
CreateDistributedPlan(planId, planContext->originalQuery, planContext->query,
|
||||
planContext->boundParams,
|
||||
|
@ -1744,8 +1739,6 @@ multi_join_restriction_hook(PlannerInfo *root,
|
|||
*/
|
||||
joinRestrictionContext->hasSemiJoin = joinRestrictionContext->hasSemiJoin ||
|
||||
extra->sjinfo->jointype == JOIN_SEMI;
|
||||
joinRestrictionContext->hasOnlyInnerJoin = joinRestrictionContext->hasOnlyInnerJoin &&
|
||||
extra->sjinfo->jointype == JOIN_INNER;
|
||||
|
||||
MemoryContextSwitchTo(oldMemoryContext);
|
||||
}
|
||||
|
@ -2135,7 +2128,6 @@ CreateAndPushPlannerRestrictionContext(void)
|
|||
|
||||
/* we'll apply logical AND as we add tables */
|
||||
plannerRestrictionContext->relationRestrictionContext->allReferenceTables = true;
|
||||
plannerRestrictionContext->joinRestrictionContext->hasOnlyInnerJoin = true;
|
||||
|
||||
plannerRestrictionContextList = lcons(plannerRestrictionContext,
|
||||
plannerRestrictionContextList);
|
||||
|
|
|
@ -151,8 +151,6 @@ static bool RangeTableArrayContainsAnyRTEIdentities(RangeTblEntry **rangeTableEn
|
|||
queryRteIdentities);
|
||||
static int RangeTableOffsetCompat(PlannerInfo *root, AppendRelInfo *appendRelInfo);
|
||||
static Relids QueryRteIdentities(Query *queryTree);
|
||||
static bool ContextCoversJoinRestriction(JoinRestrictionContext *joinRestrictionContext,
|
||||
JoinRestriction *joinRestrictionInTest);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1910,8 +1908,6 @@ FilterJoinRestrictionContext(JoinRestrictionContext *joinRestrictionContext, Rel
|
|||
* No need to re calculate has join fields as we are still operating on
|
||||
* the same query and as these values are calculated per-query basis.
|
||||
*/
|
||||
filtererdJoinRestrictionContext->hasOnlyInnerJoin =
|
||||
joinRestrictionContext->hasOnlyInnerJoin;
|
||||
filtererdJoinRestrictionContext->hasSemiJoin = joinRestrictionContext->hasSemiJoin;
|
||||
|
||||
return filtererdJoinRestrictionContext;
|
||||
|
@ -2000,105 +1996,3 @@ QueryRteIdentities(Query *queryTree)
|
|||
|
||||
return queryRteIdentities;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RemoveDuplicateJoinRestrictions gets a join restriction context and returns a
|
||||
* newly allocated join restriction context where the duplicate join restrictions
|
||||
* removed.
|
||||
*
|
||||
* Note that we use PostgreSQL hooks to accumulate the join restrictions and PostgreSQL
|
||||
* gives us all the join paths it tries while deciding on the join order. Thus, for
|
||||
* queries that has many joins, this function is likely to remove lots of duplicate join
|
||||
* restrictions. This becomes relevant for Citus on query pushdown check peformance.
|
||||
*/
|
||||
JoinRestrictionContext *
|
||||
RemoveDuplicateJoinRestrictions(JoinRestrictionContext *joinRestrictionContext)
|
||||
{
|
||||
JoinRestrictionContext *filteredContext = palloc0(sizeof(JoinRestrictionContext));
|
||||
ListCell *joinRestrictionCell = NULL;
|
||||
|
||||
filteredContext->joinRestrictionList = NIL;
|
||||
|
||||
foreach(joinRestrictionCell, joinRestrictionContext->joinRestrictionList)
|
||||
{
|
||||
JoinRestriction *joinRestriction = lfirst(joinRestrictionCell);
|
||||
|
||||
if (ContextCoversJoinRestriction(filteredContext, joinRestriction))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
filteredContext->joinRestrictionList =
|
||||
lappend(filteredContext->joinRestrictionList, joinRestriction);
|
||||
}
|
||||
|
||||
/*
|
||||
* No need to re calculate has join fields as we are still operating on
|
||||
* the same query and as these values are calculated per-query basis.
|
||||
*/
|
||||
filteredContext->hasOnlyInnerJoin = joinRestrictionContext->hasOnlyInnerJoin;
|
||||
filteredContext->hasSemiJoin = joinRestrictionContext->hasSemiJoin;
|
||||
|
||||
return filteredContext;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ContextCoversJoinRestriction returns true if the given joinRestriction
|
||||
* has an equivalent of in the given joinRestrictionContext.
|
||||
*/
|
||||
static bool
|
||||
ContextCoversJoinRestriction(JoinRestrictionContext *joinRestrictionContext,
|
||||
JoinRestriction *joinRestrictionInTest)
|
||||
{
|
||||
JoinRestriction *joinRestrictionInContext = NULL;
|
||||
List *joinRestrictionInContextList = joinRestrictionContext->joinRestrictionList;
|
||||
foreach_ptr(joinRestrictionInContext, joinRestrictionInContextList)
|
||||
{
|
||||
/* obviously we shouldn't treat different join types as being the same */
|
||||
if (joinRestrictionInContext->joinType != joinRestrictionInTest->joinType)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're dealing with different queries, we shouldn't treat their
|
||||
* restrictions as being the same.
|
||||
*/
|
||||
if (joinRestrictionInContext->plannerInfo != joinRestrictionInTest->plannerInfo)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
List *joinRestrictInfoListInTest =
|
||||
joinRestrictionInTest->joinRestrictInfoList;
|
||||
bool hasJoinRestriction = list_length(joinRestrictInfoListInTest) > 0;
|
||||
bool hasOnlyInnerJoin = joinRestrictionContext->hasOnlyInnerJoin;
|
||||
if (!hasOnlyInnerJoin && !hasJoinRestriction)
|
||||
{
|
||||
/*
|
||||
* If join doesn't have a restriction (e.g., ON (true)) and planner
|
||||
* is aware of at least one non-inner JOIN (e.g., outer/semi joins),
|
||||
* we should not eliminiate joinRestrictionInTest. It can still be
|
||||
* useful for detecting not supported outer-join checks even if it
|
||||
* doesn't help for colocation checks.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* We check whether the restrictions in joinRestrictionInTest is a subset
|
||||
* of the restrictions in joinRestrictionInContext in the sense that all the
|
||||
* restrictions in the latter already exists in the former.
|
||||
*/
|
||||
List *joinRestrictInfoListInContext =
|
||||
joinRestrictionInContext->joinRestrictInfoList;
|
||||
if (LeftListIsSubset(joinRestrictInfoListInTest, joinRestrictInfoListInContext))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -258,15 +258,3 @@ GenerateListFromElement(void *listElement, int listLength)
|
|||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* LeftListIsSubset returns true if lhs is subset of rhs list. Note that input
|
||||
* lists' entries should implement equal() function.
|
||||
*/
|
||||
bool
|
||||
LeftListIsSubset(const List *lhs, const List *rhs)
|
||||
{
|
||||
List *listDifference = list_difference(lhs, rhs);
|
||||
return list_length(listDifference) == 0;
|
||||
}
|
||||
|
|
|
@ -76,7 +76,6 @@ typedef struct JoinRestrictionContext
|
|||
{
|
||||
List *joinRestrictionList;
|
||||
bool hasSemiJoin;
|
||||
bool hasOnlyInnerJoin;
|
||||
} JoinRestrictionContext;
|
||||
|
||||
typedef struct JoinRestriction
|
||||
|
|
|
@ -93,6 +93,5 @@ extern List * ListTake(List *pointerList, int size);
|
|||
extern void * safe_list_nth(const List *list, int index);
|
||||
extern List * GeneratePositiveIntSequenceList(int upTo);
|
||||
extern List * GenerateListFromElement(void *listElement, int listLength);
|
||||
extern bool LeftListIsSubset(const List *lhs, const List *rhs);
|
||||
|
||||
#endif /* CITUS_LISTUTILS_H */
|
||||
|
|
|
@ -36,9 +36,6 @@ extern List * DistributedRelationIdList(Query *query);
|
|||
extern PlannerRestrictionContext * FilterPlannerRestrictionForQuery(
|
||||
PlannerRestrictionContext *plannerRestrictionContext,
|
||||
Query *query);
|
||||
extern JoinRestrictionContext * RemoveDuplicateJoinRestrictions(JoinRestrictionContext *
|
||||
joinRestrictionContext);
|
||||
|
||||
extern bool EquivalenceListContainsRelationsEquality(List *attributeEquivalenceList,
|
||||
RelationRestrictionContext *
|
||||
restrictionContext);
|
||||
|
|
Loading…
Reference in New Issue