Merge pull request #4264 from citusdata/remove_remove_duplicate

Remove RemoveDuplicateJoinRestrictions() function
pull/4267/head
Önder Kalacı 2020-10-21 11:34:15 +02:00 committed by GitHub
commit 808f30c1a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 0 additions and 131 deletions

View File

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

View File

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

View File

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

View File

@ -76,7 +76,6 @@ typedef struct JoinRestrictionContext
{
List *joinRestrictionList;
bool hasSemiJoin;
bool hasOnlyInnerJoin;
} JoinRestrictionContext;
typedef struct JoinRestriction

View File

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

View File

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