Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit83131e6

Browse files
committed
Avoid leaking memory while evaluating arguments for a table function.
ExecMakeTableFunctionResult evaluated the arguments for a function-in-FROMin the query-lifespan memory context. This is insignificant in simplecases where the function relation is scanned only once; but if the functionis in a sub-SELECT or is on the inside of a nested loop, any memoryconsumed during argument evaluation can add up quickly. (The potential fortrouble here had been foreseen long ago, per existing comments; but we'dnot previously seen a complaint from the field about it.) To fix, createan additional temporary context just for this purpose.Per an example from MauMau. Back-patch to all active branches.
1 parentb5c9a3b commit83131e6

File tree

4 files changed

+29
-4
lines changed

4 files changed

+29
-4
lines changed

‎src/backend/executor/execQual.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,6 +1985,7 @@ ExecMakeFunctionResultNoSets(FuncExprState *fcache,
19851985
Tuplestorestate*
19861986
ExecMakeTableFunctionResult(ExprState*funcexpr,
19871987
ExprContext*econtext,
1988+
MemoryContextargContext,
19881989
TupleDescexpectedDesc,
19891990
boolrandomAccess)
19901991
{
@@ -2063,13 +2064,19 @@ ExecMakeTableFunctionResult(ExprState *funcexpr,
20632064
/*
20642065
* Evaluate the function's argument list.
20652066
*
2066-
* Note: ideally, we'd do this in the per-tuple context, but then the
2067-
* argument values would disappear when we reset the context in the
2068-
* inner loop. So do it in caller context. Perhaps we should make a
2069-
* separate context just to hold the evaluated arguments?
2067+
* We can't do this in the per-tuple context: the argument values
2068+
* would disappear when we reset that context in the inner loop. And
2069+
* the caller's CurrentMemoryContext is typically a query-lifespan
2070+
* context, so we don't want to leak memory there. We require the
2071+
* caller to pass a separate memory context that can be used for this,
2072+
* and can be reset each time through to avoid bloat.
20702073
*/
2074+
MemoryContextReset(argContext);
2075+
oldcontext=MemoryContextSwitchTo(argContext);
20712076
fcinfo.flinfo=&(fcache->func);
20722077
argDone=ExecEvalFuncArgs(&fcinfo,fcache->args,econtext);
2078+
MemoryContextSwitchTo(oldcontext);
2079+
20732080
/* We don't allow sets in the arguments of the table function */
20742081
if (argDone!=ExprSingleResult)
20752082
ereport(ERROR,

‎src/backend/executor/nodeFunctionscan.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include"executor/nodeFunctionscan.h"
2626
#include"funcapi.h"
2727
#include"utils/builtins.h"
28+
#include"utils/memutils.h"
2829

2930

3031
staticTupleTableSlot*FunctionNext(FunctionScanState*node);
@@ -64,6 +65,7 @@ FunctionNext(FunctionScanState *node)
6465
node->tuplestorestate=tuplestorestate=
6566
ExecMakeTableFunctionResult(node->funcexpr,
6667
node->ss.ps.ps_ExprContext,
68+
node->argcontext,
6769
node->tupdesc,
6870
node->eflags&EXEC_FLAG_BACKWARD);
6971
}
@@ -223,6 +225,19 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
223225
ExecAssignResultTypeFromTL(&scanstate->ss.ps);
224226
ExecAssignScanProjectionInfo(&scanstate->ss);
225227

228+
/*
229+
* Create a memory context that ExecMakeTableFunctionResult can use to
230+
* evaluate function arguments in. We can't use the per-tuple context for
231+
* this because it gets reset too often; but we don't want to leak
232+
* evaluation results into the query-lifespan context either. We just
233+
* need one context, because we evaluate each function separately.
234+
*/
235+
scanstate->argcontext=AllocSetContextCreate(CurrentMemoryContext,
236+
"Table function arguments",
237+
ALLOCSET_DEFAULT_MINSIZE,
238+
ALLOCSET_DEFAULT_INITSIZE,
239+
ALLOCSET_DEFAULT_MAXSIZE);
240+
226241
returnscanstate;
227242
}
228243

‎src/include/executor/executor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ extern Datum GetAttributeByName(HeapTupleHeader tuple, const char *attname,
207207
bool*isNull);
208208
externTuplestorestate*ExecMakeTableFunctionResult(ExprState*funcexpr,
209209
ExprContext*econtext,
210+
MemoryContextargContext,
210211
TupleDescexpectedDesc,
211212
boolrandomAccess);
212213
externDatumExecEvalExprSwitchContext(ExprState*expression,ExprContext*econtext,

‎src/include/nodes/execnodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,7 @@ typedef struct SubqueryScanState
13151315
*tupdescexpected return tuple description
13161316
*tuplestorestateprivate state of tuplestore.c
13171317
*funcexprstate for function expression being evaluated
1318+
*argcontextmemory context to evaluate function arguments in
13181319
* ----------------
13191320
*/
13201321
typedefstructFunctionScanState
@@ -1324,6 +1325,7 @@ typedef struct FunctionScanState
13241325
TupleDesctupdesc;
13251326
Tuplestorestate*tuplestorestate;
13261327
ExprState*funcexpr;
1328+
MemoryContextargcontext;
13271329
}FunctionScanState;
13281330

13291331
/* ----------------

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp