Skip to content

Commit 7f528e9

Browse files
committed
Use per-tuple context in ExecGetAllUpdatedCols
Commit fc22b66 (generated columns) replaced ExecGetUpdatedCols() with ExecGetAllUpdatedCols() in a couple places handling UPDATE (triggers and lock mode). However, ExecGetUpdatedCols() did exec_rt_fetch() while ExecGetAllUpdatedCols() also allocates memory through bms_union() without paying attention to the memory context and happened to use the long-lived ExecutorState, leaking the memory until the end of the query. The amount of leaked memory is proportional to the number of (updated) attributes, types of UPDATE triggers, and the number of processed rows (which for UPDATE ... FROM ... may be much higher than updated rows). Fixed by switching to the per-tuple context in GetAllUpdatedColumns(). This is fine for all in-core callers, but external callers may need to copy the result. But we're not aware of any such callers. Note the issue was introduced by fc22b66, but the macros were later renamed by f50e888. Backpatch to 12, where the issue was introduced. Reported-by: Tomas Vondra Reviewed-by: Andres Freund, Tom Lane, Jakub Wartak Backpatch-through: 12 Discussion: https://postgr.es/m/222a3442-7f7d-246c-ed9b-a76209d19239@enterprisedb.com
1 parent 525ec83 commit 7f528e9

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

src/backend/executor/execUtils.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,10 +1348,25 @@ ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate)
13481348
return NULL;
13491349
}
13501350

1351-
/* Return columns being updated, including generated columns */
1351+
/*
1352+
* Return columns being updated, including generated columns
1353+
*
1354+
* The bitmap is allocated in per-tuple memory context. It's up to the caller to
1355+
* copy it into a different context with the appropriate lifespan, if needed.
1356+
*/
13521357
Bitmapset *
13531358
ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate)
13541359
{
1355-
return bms_union(ExecGetUpdatedCols(relinfo, estate),
1356-
ExecGetExtraUpdatedCols(relinfo, estate));
1360+
1361+
Bitmapset *ret;
1362+
MemoryContext oldcxt;
1363+
1364+
oldcxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
1365+
1366+
ret = bms_union(ExecGetUpdatedCols(relinfo, estate),
1367+
ExecGetExtraUpdatedCols(relinfo, estate));
1368+
1369+
MemoryContextSwitchTo(oldcxt);
1370+
1371+
return ret;
13571372
}

0 commit comments

Comments
 (0)