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
Message: 回复:BUG #19040: Memory leak in hashed subplan node due to missing hashtempcxt reset

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.