The common attribute equivalance class always includes the input relations

We added the ability to filter out the planner restriction information
for specific parts of the query. This might lead to situations where
the common restriction includes some other relations that we're searching
for. The reason is that while filtering for join restrictions, we add the
restriction as soon as we find the relation.

With this commit we make sure that the common attribute
equivalance class always includes the input relations.
pull/1838/head
Onder Kalaci 2017-11-28 20:54:07 +02:00
parent 8cb5734481
commit a273711500
1 changed files with 59 additions and 7 deletions

View File

@ -113,7 +113,13 @@ static bool AttributeEquivalancesAreEqual(AttributeEquivalenceClass *
AttributeEquivalenceClass * AttributeEquivalenceClass *
secondAttributeEquivalance); secondAttributeEquivalance);
static AttributeEquivalenceClass * GenerateCommonEquivalence(List * static AttributeEquivalenceClass * GenerateCommonEquivalence(List *
attributeEquivalenceList); attributeEquivalenceList,
RelationRestrictionContext *
relationRestrictionContext);
static AttributeEquivalenceClass * GenerateEquivalanceClassForRelationRestriction(
RelationRestrictionContext
*
relationRestrictionContext);
static void ListConcatUniqueAttributeClassMemberLists(AttributeEquivalenceClass ** static void ListConcatUniqueAttributeClassMemberLists(AttributeEquivalenceClass **
firstClass, firstClass,
AttributeEquivalenceClass * AttributeEquivalenceClass *
@ -478,7 +484,8 @@ EquivalenceListContainsRelationsEquality(List *attributeEquivalenceList,
* common equivalence class. The main goal is to test whether this main class * common equivalence class. The main goal is to test whether this main class
* contains all partition keys of the existing relations. * contains all partition keys of the existing relations.
*/ */
commonEquivalenceClass = GenerateCommonEquivalence(attributeEquivalenceList); commonEquivalenceClass = GenerateCommonEquivalence(attributeEquivalenceList,
restrictionContext);
/* add the rte indexes of relations to a bitmap */ /* add the rte indexes of relations to a bitmap */
foreach(commonEqClassCell, commonEquivalenceClass->equivalentAttributes) foreach(commonEqClassCell, commonEquivalenceClass->equivalentAttributes)
@ -707,7 +714,8 @@ GetVarFromAssignedParam(List *parentPlannerParamList, Param *plannerParam)
* - Finally, return the common equivalence class. * - Finally, return the common equivalence class.
*/ */
static AttributeEquivalenceClass * static AttributeEquivalenceClass *
GenerateCommonEquivalence(List *attributeEquivalenceList) GenerateCommonEquivalence(List *attributeEquivalenceList,
RelationRestrictionContext *relationRestrictionContext)
{ {
AttributeEquivalenceClass *commonEquivalenceClass = NULL; AttributeEquivalenceClass *commonEquivalenceClass = NULL;
AttributeEquivalenceClass *firstEquivalenceClass = NULL; AttributeEquivalenceClass *firstEquivalenceClass = NULL;
@ -718,14 +726,20 @@ GenerateCommonEquivalence(List *attributeEquivalenceList)
commonEquivalenceClass = palloc0(sizeof(AttributeEquivalenceClass)); commonEquivalenceClass = palloc0(sizeof(AttributeEquivalenceClass));
commonEquivalenceClass->equivalenceId = 0; commonEquivalenceClass->equivalenceId = 0;
/* think more on this. */ /*
if (equivalenceListSize < 1) * We seed the common equivalence class with a the first distributed
* table since we always want the input distributed relations to be
* on the common class.
*/
firstEquivalenceClass =
GenerateEquivalanceClassForRelationRestriction(relationRestrictionContext);
/* we skip the calculation if there are not enough information */
if (equivalenceListSize < 1 || firstEquivalenceClass == NULL)
{ {
return commonEquivalenceClass; return commonEquivalenceClass;
} }
/* setup the initial state of the main equivalence class */
firstEquivalenceClass = linitial(attributeEquivalenceList);
commonEquivalenceClass->equivalentAttributes = commonEquivalenceClass->equivalentAttributes =
firstEquivalenceClass->equivalentAttributes; firstEquivalenceClass->equivalentAttributes;
addedEquivalenceIds = bms_add_member(addedEquivalenceIds, addedEquivalenceIds = bms_add_member(addedEquivalenceIds,
@ -778,6 +792,44 @@ GenerateCommonEquivalence(List *attributeEquivalenceList)
} }
/*
* GenerateEquivalanceClassForRelationRestriction generates an AttributeEquivalenceClass
* with a single AttributeEquivalenceClassMember.
*/
static AttributeEquivalenceClass *
GenerateEquivalanceClassForRelationRestriction(
RelationRestrictionContext *relationRestrictionContext)
{
ListCell *relationRestrictionCell = NULL;
AttributeEquivalenceClassMember *eqMember = NULL;
AttributeEquivalenceClass *eqClassForRelation = NULL;
foreach(relationRestrictionCell, relationRestrictionContext->relationRestrictionList)
{
RelationRestriction *relationRestriction =
(RelationRestriction *) lfirst(relationRestrictionCell);
Var *relationPartitionKey = DistPartitionKey(relationRestriction->relationId);
if (relationPartitionKey)
{
eqClassForRelation = palloc0(sizeof(AttributeEquivalenceClass));
eqMember = palloc0(sizeof(AttributeEquivalenceClassMember));
eqMember->relationId = relationRestriction->relationId;
eqMember->rteIdentity = GetRTEIdentity(relationRestriction->rte);
eqMember->varno = relationRestriction->index;
eqMember->varattno = relationPartitionKey->varattno;
eqClassForRelation->equivalentAttributes =
lappend(eqClassForRelation->equivalentAttributes, eqMember);
break;
}
}
return eqClassForRelation;
}
/* /*
* ListConcatUniqueAttributeClassMemberLists gets two attribute equivalence classes. It * ListConcatUniqueAttributeClassMemberLists gets two attribute equivalence classes. It
* basically concatenates attribute equivalence member lists uniquely and updates the * basically concatenates attribute equivalence member lists uniquely and updates the