Decide what group to convert, then convert them all in one go

pull/4358/head
Sait Talha Nisanci 2020-12-11 17:50:02 +03:00
parent c4d3927956
commit d5b0f02a64
2 changed files with 52 additions and 69 deletions

View File

@ -135,7 +135,6 @@ int LocalTableJoinPolicy = LOCAL_JOIN_POLICY_AUTO;
typedef struct RangeTableEntryDetails typedef struct RangeTableEntryDetails
{ {
RangeTblEntry *rangeTableEntry; RangeTblEntry *rangeTableEntry;
int rteIdentity;
List *requiredAttributeNumbers; List *requiredAttributeNumbers;
bool hasConstantFilterOnUniqueColumn; bool hasConstantFilterOnUniqueColumn;
} RangeTableEntryDetails; } RangeTableEntryDetails;
@ -151,6 +150,12 @@ typedef struct IndexColumns
List *indexColumnNos; List *indexColumnNos;
}IndexColumns; }IndexColumns;
typedef enum ConversionChoice
{
CONVERT_LOCAL_TABLES = 1,
CONVERT_DISTRIBUTED_TABLES = 2
}ConversionChoice;
static bool HasConstantFilterOnUniqueColumn(RangeTblEntry *rangeTableEntry, static bool HasConstantFilterOnUniqueColumn(RangeTblEntry *rangeTableEntry,
RelationRestriction *relationRestriction); RelationRestriction *relationRestriction);
static List * RequiredAttrNumbersForRelation(RangeTblEntry *relationRte, static List * RequiredAttrNumbersForRelation(RangeTblEntry *relationRte,
@ -161,14 +166,14 @@ static ConversionCandidates * CreateConversionCandidates(PlannerRestrictionConte
List *rangeTableList, List *rangeTableList,
int resultRTEIdentity); int resultRTEIdentity);
static void AppendUniqueIndexColumnsToList(Form_pg_index indexForm, List **uniqueIndexes); static void AppendUniqueIndexColumnsToList(Form_pg_index indexForm, List **uniqueIndexes);
static RangeTableEntryDetails * GetNextRTEToConvertToSubquery(ConversionCandidates * static ConversionChoice GetConversionChoice(ConversionCandidates *
conversionCandidates, conversionCandidates,
PlannerRestrictionContext * PlannerRestrictionContext *
plannerRestrictionContext); plannerRestrictionContext);
static void RemoveFromConversionCandidates(ConversionCandidates *conversionCandidates,
int rteIdentity);
static bool AllRangeTableEntriesHaveUniqueIndex(List *rangeTableEntryDetailsList); static bool AllRangeTableEntriesHaveUniqueIndex(List *rangeTableEntryDetailsList);
static bool FirstIsSuperSetOfSecond(List *firstIntList, List *secondIntList); static bool FirstIsSuperSetOfSecond(List *firstIntList, List *secondIntList);
static void ConvertRTEsToSubquery(List *rangeTableEntryDetailsList,
RecursivePlanningContext *context);
/* /*
* RecursivelyPlanLocalTableJoins gets a query and the planner * RecursivelyPlanLocalTableJoins gets a query and the planner
@ -192,35 +197,27 @@ RecursivelyPlanLocalTableJoins(Query *query,
CreateConversionCandidates(plannerRestrictionContext, CreateConversionCandidates(plannerRestrictionContext,
rangeTableList, resultRTEIdentity); rangeTableList, resultRTEIdentity);
while (ShouldConvertLocalTableJoinsToSubqueries(query, rangeTableList, ConversionChoice conversionChoise =
plannerRestrictionContext)) GetConversionChoice(conversionCandidates, plannerRestrictionContext);
{
RangeTableEntryDetails *rangeTableEntryDetails =
GetNextRTEToConvertToSubquery(conversionCandidates,
plannerRestrictionContext);
if (rangeTableEntryDetails == NULL)
{
break;
}
RangeTblEntry *rangeTableEntry = rangeTableEntryDetails->rangeTableEntry; if (conversionChoise == CONVERT_LOCAL_TABLES)
List *requiredAttributeNumbers = rangeTableEntryDetails->requiredAttributeNumbers; {
ReplaceRTERelationWithRteSubquery(rangeTableEntry, ConvertRTEsToSubquery(conversionCandidates->localTableList, context);
requiredAttributeNumbers, context); }
int rteIdentity = rangeTableEntryDetails->rteIdentity; else
RemoveFromConversionCandidates(conversionCandidates, rteIdentity); {
ConvertRTEsToSubquery(conversionCandidates->distributedTableList, context);
} }
} }
/* /*
* GetNextRTEToConvertToSubquery returns the range table entry * GetConversionChoice returns the conversion choice considering the local table
* which should be converted to a subquery. It considers the local join policy * join policy.
* for conversion priorities.
*/ */
static RangeTableEntryDetails * static ConversionChoice
GetNextRTEToConvertToSubquery(ConversionCandidates *conversionCandidates, GetConversionChoice(ConversionCandidates *conversionCandidates,
PlannerRestrictionContext *plannerRestrictionContext) PlannerRestrictionContext *plannerRestrictionContext)
{ {
RangeTableEntryDetails *localRTECandidate = NULL; RangeTableEntryDetails *localRTECandidate = NULL;
RangeTableEntryDetails *distributedRTECandidate = NULL; RangeTableEntryDetails *distributedRTECandidate = NULL;
@ -236,11 +233,12 @@ GetNextRTEToConvertToSubquery(ConversionCandidates *conversionCandidates,
if (LocalTableJoinPolicy == LOCAL_JOIN_POLICY_PREFER_LOCAL) if (LocalTableJoinPolicy == LOCAL_JOIN_POLICY_PREFER_LOCAL)
{ {
return localRTECandidate ? localRTECandidate : distributedRTECandidate; return localRTECandidate ? CONVERT_LOCAL_TABLES : CONVERT_DISTRIBUTED_TABLES;
} }
else if (LocalTableJoinPolicy == LOCAL_JOIN_POLICY_PREFER_DISTRIBUTED) else if (LocalTableJoinPolicy == LOCAL_JOIN_POLICY_PREFER_DISTRIBUTED)
{ {
return distributedRTECandidate ? distributedRTECandidate : localRTECandidate; return distributedRTECandidate ? CONVERT_DISTRIBUTED_TABLES :
CONVERT_LOCAL_TABLES;
} }
else else
{ {
@ -254,16 +252,35 @@ GetNextRTEToConvertToSubquery(ConversionCandidates *conversionCandidates,
if (allRangeTableEntriesHaveUniqueIndex) if (allRangeTableEntriesHaveUniqueIndex)
{ {
return distributedRTECandidate ? distributedRTECandidate : localRTECandidate; return distributedRTECandidate ? CONVERT_DISTRIBUTED_TABLES :
CONVERT_LOCAL_TABLES;
} }
else else
{ {
return localRTECandidate ? localRTECandidate : distributedRTECandidate; return localRTECandidate ? CONVERT_LOCAL_TABLES : CONVERT_DISTRIBUTED_TABLES;
} }
} }
} }
/*
* ConvertRTEsToSubquery converts all the given range table entries
* to a subquery.
*/
static void
ConvertRTEsToSubquery(List *rangeTableEntryDetailsList, RecursivePlanningContext *context)
{
RangeTableEntryDetails *rangeTableEntryDetails = NULL;
foreach_ptr(rangeTableEntryDetails, rangeTableEntryDetailsList)
{
RangeTblEntry *rangeTableEntry = rangeTableEntryDetails->rangeTableEntry;
List *requiredAttributeNumbers = rangeTableEntryDetails->requiredAttributeNumbers;
ReplaceRTERelationWithRteSubquery(rangeTableEntry,
requiredAttributeNumbers, context);
}
}
/* /*
* AllRangeTableEntriesHaveUniqueIndex returns true if all of the RTE's in the given * AllRangeTableEntriesHaveUniqueIndex returns true if all of the RTE's in the given
* list have a unique index. * list have a unique index.
@ -283,41 +300,6 @@ AllRangeTableEntriesHaveUniqueIndex(List *rangeTableEntryDetailsList)
} }
/*
* RemoveFromConversionCandidates removes an element from
* the relevant list based on the relation id.
*/
static void
RemoveFromConversionCandidates(ConversionCandidates *conversionCandidates, int
rteIdentity)
{
RangeTableEntryDetails *rangeTableEntryDetails = NULL;
foreach_ptr(rangeTableEntryDetails, conversionCandidates->localTableList)
{
if (rangeTableEntryDetails->rteIdentity == rteIdentity)
{
conversionCandidates->localTableList =
list_delete_ptr(conversionCandidates->localTableList,
rangeTableEntryDetails);
return;
}
}
foreach_ptr(rangeTableEntryDetails, conversionCandidates->distributedTableList)
{
if (rangeTableEntryDetails->rteIdentity == rteIdentity)
{
conversionCandidates->distributedTableList =
list_delete_ptr(conversionCandidates->distributedTableList,
rangeTableEntryDetails);
return;
}
}
ereport(ERROR, (errmsg("invalid rte index is given :%d", rteIdentity)));
}
/* /*
* ShouldConvertLocalTableJoinsToSubqueries returns true if we should * ShouldConvertLocalTableJoinsToSubqueries returns true if we should
* convert local-dist table joins to subqueries. * convert local-dist table joins to subqueries.
@ -506,7 +488,6 @@ CreateConversionCandidates(PlannerRestrictionContext *plannerRestrictionContext,
palloc0(sizeof(RangeTableEntryDetails)); palloc0(sizeof(RangeTableEntryDetails));
rangeTableEntryDetails->rangeTableEntry = rangeTableEntry; rangeTableEntryDetails->rangeTableEntry = rangeTableEntry;
rangeTableEntryDetails->rteIdentity = rteIdentity;
rangeTableEntryDetails->requiredAttributeNumbers = rangeTableEntryDetails->requiredAttributeNumbers =
RequiredAttrNumbersForRelation(rangeTableEntry, plannerRestrictionContext); RequiredAttrNumbersForRelation(rangeTableEntry, plannerRestrictionContext);
rangeTableEntryDetails->hasConstantFilterOnUniqueColumn = rangeTableEntryDetails->hasConstantFilterOnUniqueColumn =

View File

@ -1793,6 +1793,7 @@ TransformFunctionRTE(RangeTblEntry *rangeTblEntry)
subquery->targetList = lappend(subquery->targetList, targetEntry); subquery->targetList = lappend(subquery->targetList, targetEntry);
} }
} }
/* /*
* If tupleDesc is NULL we have 2 different cases: * If tupleDesc is NULL we have 2 different cases:
* *
@ -1842,6 +1843,7 @@ TransformFunctionRTE(RangeTblEntry *rangeTblEntry)
columnType = list_nth_oid(rangeTblFunction->funccoltypes, columnType = list_nth_oid(rangeTblFunction->funccoltypes,
targetColumnIndex); targetColumnIndex);
} }
/* use the types in the function definition otherwise */ /* use the types in the function definition otherwise */
else else
{ {