v02_fix_memory_leak_in_hashed_subplan_node.patch
application/octet-stream
Filename: v02_fix_memory_leak_in_hashed_subplan_node.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v2
| File | + | − |
|---|---|---|
| src/backend/executor/nodeSubplan.c | 28 | 13 |
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.