mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-28 11:55:03 +03:00 
			
		
		
		
	Fix intra-query memory leakage in nodeProjectSet.c.
Both ExecMakeFunctionResultSet() and evaluation of simple expressions need to be done in the per-tuple memory context, not per-query, else we leak data until end of query. This is a consideration that was missed while refactoring code in the ProjectSet patch (note that in pre-v10, ExecMakeFunctionResult is called in the per-tuple context). Per bug #14843 from Ben M. Diagnosed independently by Andres and myself. Discussion: https://postgr.es/m/20171005230321.28561.15927@wrigleys.postgresql.org
This commit is contained in:
		| @@ -467,6 +467,8 @@ ExecInitFunctionResultSet(Expr *expr, | ||||
|  * function itself.  The argument expressions may not contain set-returning | ||||
|  * functions (the planner is supposed to have separated evaluation for those). | ||||
|  * | ||||
|  * This should be called in a short-lived (per-tuple) context. | ||||
|  * | ||||
|  * This is used by nodeProjectSet.c. | ||||
|  */ | ||||
| Datum | ||||
|   | ||||
| @@ -124,12 +124,16 @@ ExecProjectSRF(ProjectSetState *node, bool continuing) | ||||
| { | ||||
| 	TupleTableSlot *resultSlot = node->ps.ps_ResultTupleSlot; | ||||
| 	ExprContext *econtext = node->ps.ps_ExprContext; | ||||
| 	MemoryContext oldcontext; | ||||
| 	bool		hassrf PG_USED_FOR_ASSERTS_ONLY; | ||||
| 	bool		hasresult; | ||||
| 	int			argno; | ||||
|  | ||||
| 	ExecClearTuple(resultSlot); | ||||
|  | ||||
| 	/* Call SRFs, as well as plain expressions, in per-tuple context */ | ||||
| 	oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory); | ||||
|  | ||||
| 	/* | ||||
| 	 * Assume no further tuples are produced unless an ExprMultipleResult is | ||||
| 	 * encountered from a set returning function. | ||||
| @@ -176,6 +180,8 @@ ExecProjectSRF(ProjectSetState *node, bool continuing) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	MemoryContextSwitchTo(oldcontext); | ||||
|  | ||||
| 	/* ProjectSet should not be used if there's no SRFs */ | ||||
| 	Assert(hassrf); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user