Fix check-vanilla tests

It semms that GEQO optimizations, when it is set to on, create their own memory context
and free it after when it is no longer necessary. In join multi_join_restriction_hook
we allocate our variables in the CurrentMemoryContext, which is GEQO's memory context
if it is active. To prevent deallocation of our variables when GEQO's memory context is
freed, we started to allocate memory fo these variables in separate MemoryContext.
pull/1349/head
Burak Yucesoy 2017-04-25 13:13:51 +03:00 committed by Marco Slot
parent b0fdd5963d
commit 6599677902
2 changed files with 56 additions and 47 deletions

View File

@ -72,8 +72,7 @@ static PlannedStmt * FinalizeRouterPlan(PlannedStmt *localPlan, CustomScan *cust
static void CheckNodeIsDumpable(Node *node); static void CheckNodeIsDumpable(Node *node);
static List * CopyPlanParamList(List *originalPlanParamList); static List * CopyPlanParamList(List *originalPlanParamList);
static PlannerRestrictionContext * CreateAndPushPlannerRestrictionContext(void); static PlannerRestrictionContext * CreateAndPushPlannerRestrictionContext(void);
static RelationRestrictionContext * CurrentRelationRestrictionContext(void); static PlannerRestrictionContext * CurrentPlannerRestrictionContext(void);
static JoinRestrictionContext * CurrentJoinRestrictionContext(void);
static void PopPlannerRestrictionContext(void); static void PopPlannerRestrictionContext(void);
static bool HasUnresolvedExternParamsWalker(Node *expression, ParamListInfo boundParams); static bool HasUnresolvedExternParamsWalker(Node *expression, ParamListInfo boundParams);
@ -658,20 +657,40 @@ multi_join_restriction_hook(PlannerInfo *root,
JoinType jointype, JoinType jointype,
JoinPathExtraData *extra) JoinPathExtraData *extra)
{ {
JoinRestrictionContext *joinContext = NULL; PlannerRestrictionContext *plannerRestrictionContext = NULL;
JoinRestriction *joinRestriction = palloc0(sizeof(JoinRestriction)); JoinRestrictionContext *joinRestrictionContext = NULL;
JoinRestriction *joinRestriction = NULL;
MemoryContext restrictionsMemoryContext = NULL;
MemoryContext oldMemoryContext = NULL;
List *restrictInfoList = NIL; List *restrictInfoList = NIL;
restrictInfoList = extra->restrictlist; /*
joinContext = CurrentJoinRestrictionContext(); * Use a memory context that's guaranteed to live long enough, could be
Assert(joinContext != NULL); * called in a more shorted lived one (e.g. with GEQO).
*/
plannerRestrictionContext = CurrentPlannerRestrictionContext();
restrictionsMemoryContext = plannerRestrictionContext->memoryContext;
oldMemoryContext = MemoryContextSwitchTo(restrictionsMemoryContext);
/*
* We create a copy of restrictInfoList because it may be created in a memory
* context which will be deleted when we still need it, thus we create a copy
* of it in our memory context.
*/
restrictInfoList = copyObject(extra->restrictlist);
joinRestrictionContext = plannerRestrictionContext->joinRestrictionContext;
Assert(joinRestrictionContext != NULL);
joinRestriction = palloc0(sizeof(JoinRestriction));
joinRestriction->joinType = jointype; joinRestriction->joinType = jointype;
joinRestriction->joinRestrictInfoList = restrictInfoList; joinRestriction->joinRestrictInfoList = restrictInfoList;
joinRestriction->plannerInfo = root; joinRestriction->plannerInfo = root;
joinContext->joinRestrictionList = joinRestrictionContext->joinRestrictionList =
lappend(joinContext->joinRestrictionList, joinRestriction); lappend(joinRestrictionContext->joinRestrictionList, joinRestriction);
MemoryContextSwitchTo(oldMemoryContext);
} }
@ -684,7 +703,10 @@ void
multi_relation_restriction_hook(PlannerInfo *root, RelOptInfo *relOptInfo, Index index, multi_relation_restriction_hook(PlannerInfo *root, RelOptInfo *relOptInfo, Index index,
RangeTblEntry *rte) RangeTblEntry *rte)
{ {
RelationRestrictionContext *restrictionContext = NULL; PlannerRestrictionContext *plannerRestrictionContext = NULL;
RelationRestrictionContext *relationRestrictionContext = NULL;
MemoryContext restrictionsMemoryContext = NULL;
MemoryContext oldMemoryContext = NULL;
RelationRestriction *relationRestriction = NULL; RelationRestriction *relationRestriction = NULL;
DistTableCacheEntry *cacheEntry = NULL; DistTableCacheEntry *cacheEntry = NULL;
bool distributedTable = false; bool distributedTable = false;
@ -695,12 +717,17 @@ multi_relation_restriction_hook(PlannerInfo *root, RelOptInfo *relOptInfo, Index
return; return;
} }
/*
* Use a memory context that's guaranteed to live long enough, could be
* called in a more shorted lived one (e.g. with GEQO).
*/
plannerRestrictionContext = CurrentPlannerRestrictionContext();
restrictionsMemoryContext = plannerRestrictionContext->memoryContext;
oldMemoryContext = MemoryContextSwitchTo(restrictionsMemoryContext);
distributedTable = IsDistributedTable(rte->relid); distributedTable = IsDistributedTable(rte->relid);
localTable = !distributedTable; localTable = !distributedTable;
restrictionContext = CurrentRelationRestrictionContext();
Assert(restrictionContext != NULL);
relationRestriction = palloc0(sizeof(RelationRestriction)); relationRestriction = palloc0(sizeof(RelationRestriction));
relationRestriction->index = index; relationRestriction->index = index;
relationRestriction->relationId = rte->relid; relationRestriction->relationId = rte->relid;
@ -718,8 +745,9 @@ multi_relation_restriction_hook(PlannerInfo *root, RelOptInfo *relOptInfo, Index
CopyPlanParamList(root->parent_root->plan_params); CopyPlanParamList(root->parent_root->plan_params);
} }
restrictionContext->hasDistributedRelation |= distributedTable; relationRestrictionContext = plannerRestrictionContext->relationRestrictionContext;
restrictionContext->hasLocalRelation |= localTable; relationRestrictionContext->hasDistributedRelation |= distributedTable;
relationRestrictionContext->hasLocalRelation |= localTable;
/* /*
* We're also keeping track of whether all participant * We're also keeping track of whether all participant
@ -729,12 +757,14 @@ multi_relation_restriction_hook(PlannerInfo *root, RelOptInfo *relOptInfo, Index
{ {
cacheEntry = DistributedTableCacheEntry(rte->relid); cacheEntry = DistributedTableCacheEntry(rte->relid);
restrictionContext->allReferenceTables &= relationRestrictionContext->allReferenceTables &=
(cacheEntry->partitionMethod == DISTRIBUTE_BY_NONE); (cacheEntry->partitionMethod == DISTRIBUTE_BY_NONE);
} }
restrictionContext->relationRestrictionList = relationRestrictionContext->relationRestrictionList =
lappend(restrictionContext->relationRestrictionList, relationRestriction); lappend(relationRestrictionContext->relationRestrictionList, relationRestriction);
MemoryContextSwitchTo(oldMemoryContext);
} }
@ -784,6 +814,8 @@ CreateAndPushPlannerRestrictionContext(void)
plannerRestrictionContext->joinRestrictionContext = plannerRestrictionContext->joinRestrictionContext =
palloc0(sizeof(JoinRestrictionContext)); palloc0(sizeof(JoinRestrictionContext));
plannerRestrictionContext->memoryContext = CurrentMemoryContext;
/* we'll apply logical AND as we add tables */ /* we'll apply logical AND as we add tables */
plannerRestrictionContext->relationRestrictionContext->allReferenceTables = true; plannerRestrictionContext->relationRestrictionContext->allReferenceTables = true;
@ -795,44 +827,20 @@ CreateAndPushPlannerRestrictionContext(void)
/* /*
* CurrentRelationRestrictionContext returns the the last restriction context from the * CurrentRestrictionContext returns the the most recently added
* relationRestrictionContext list. * PlannerRestrictionContext from the plannerRestrictionContextList list.
*/ */
static RelationRestrictionContext * static PlannerRestrictionContext *
CurrentRelationRestrictionContext(void) CurrentPlannerRestrictionContext(void)
{ {
PlannerRestrictionContext *plannerRestrictionContext = NULL; PlannerRestrictionContext *plannerRestrictionContext = NULL;
RelationRestrictionContext *relationRestrictionContext = NULL;
Assert(plannerRestrictionContextList != NIL); Assert(plannerRestrictionContextList != NIL);
plannerRestrictionContext = plannerRestrictionContext =
(PlannerRestrictionContext *) linitial(plannerRestrictionContextList); (PlannerRestrictionContext *) linitial(plannerRestrictionContextList);
relationRestrictionContext = plannerRestrictionContext->relationRestrictionContext; return plannerRestrictionContext;
return relationRestrictionContext;
}
/*
* CurrentJoinRestrictionContext returns the the last restriction context from the
* list.
*/
static JoinRestrictionContext *
CurrentJoinRestrictionContext(void)
{
PlannerRestrictionContext *plannerRestrictionContext = NULL;
JoinRestrictionContext *joinRestrictionContext = NULL;
Assert(plannerRestrictionContextList != NIL);
plannerRestrictionContext =
(PlannerRestrictionContext *) linitial(plannerRestrictionContextList);
joinRestrictionContext = plannerRestrictionContext->joinRestrictionContext;
return joinRestrictionContext;
} }

View File

@ -58,6 +58,7 @@ typedef struct PlannerRestrictionContext
{ {
RelationRestrictionContext *relationRestrictionContext; RelationRestrictionContext *relationRestrictionContext;
JoinRestrictionContext *joinRestrictionContext; JoinRestrictionContext *joinRestrictionContext;
MemoryContext memoryContext;
} PlannerRestrictionContext; } PlannerRestrictionContext;
typedef struct RelationShard typedef struct RelationShard