diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index f7f6fc2da0b..3864949c6fa 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -105,6 +105,7 @@ ExecHashSubPlan(SubPlanState *node, SubPlan *subplan = node->subplan; PlanState *planstate = node->planstate; TupleTableSlot *slot; + bool result = false; /* Shouldn't have any direct correlation Vars */ if (subplan->parParam != NIL || subplan->args != NIL) @@ -162,18 +163,19 @@ ExecHashSubPlan(SubPlanState *node, node->cur_eq_comp, node->lhs_hash_expr) != NULL) { - ExecClearTuple(slot); - return BoolGetDatum(true); + result = true; + goto out; } if (node->havenullrows && findPartialMatch(node->hashnulls, slot, node->cur_eq_funcs)) { - ExecClearTuple(slot); *isNull = true; - return BoolGetDatum(false); + result = false; + goto out; } - ExecClearTuple(slot); - return BoolGetDatum(false); + + result = false; + goto out; } /* @@ -188,14 +190,14 @@ ExecHashSubPlan(SubPlanState *node, */ if (node->hashnulls == NULL) { - ExecClearTuple(slot); - return BoolGetDatum(false); + result = false; + goto out; } if (slotAllNulls(slot)) { - ExecClearTuple(slot); *isNull = true; - return BoolGetDatum(false); + result = false; + goto out; } /* Scan partly-null table first, since more likely to get a match */ if (node->havenullrows && @@ -203,17 +205,26 @@ ExecHashSubPlan(SubPlanState *node, { ExecClearTuple(slot); *isNull = true; - return BoolGetDatum(false); + result = false; + goto out; } if (node->havehashrows && findPartialMatch(node->hashtable, slot, node->cur_eq_funcs)) { ExecClearTuple(slot); *isNull = true; - return BoolGetDatum(false); + result = false; + goto out; } + +out: ExecClearTuple(slot); - return BoolGetDatum(false); + /* + * Lifespan of hashtempcxt is over. Reset it to release hash function + * evaluation memory. + */ + MemoryContextReset(node->hashtempcxt); + return BoolGetDatum(result); } /* @@ -637,6 +648,10 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) node->havenullrows = true; } + /* + * Reset hash temp context after each hashtable lookup. + */ + MemoryContextReset(node->hashtempcxt); /* * Reset innerecontext after each inner tuple to free any memory used * during ExecProject.