Re: BUG #19480: PL/Python SRF crashes (SIGSEGV) when function is replaced mid-iteration: use-after-free in PLy_funct
Matheus Alcantara <matheusssilv97@gmail.com>
From: "Matheus Alcantara" <matheusssilv97@gmail.com>
To: "Tom Lane" <tgl@sss.pgh.pa.us>
Cc: <adoros@starfishstorage.com>, <pgsql-bugs@lists.postgresql.org>
Date: 2026-06-05T18:09:26Z
Lists: pgsql-bugs
Attachments
- v1-0001-plpython-Use-funccache.c-infrastructure-for-proce.patch (text/plain) patch v1-0001
On Mon Jun 1, 2026 at 8:26 PM -03, Tom Lane wrote: > Yeah, that was my suspicion as well. funccache.c exists because > I realized that SQL-language functions (executor/functions.c) were > going to need logic that plpgsql had had for years. > > Actually ... if memory serves, SQL-language functions use ValuePerCall > mode, so there probably already is a solution to this embedded in > functions.c. Did you look at that? > I dind't look at this before but this was exactly the right call. SQL functions handle this by maintaining a per-call-site cache struct (SQLFunctionCache) in fn_extra that holds both the pointer to the long-lived hash entry and the execution state. The use_count is incremented when we first obtain the function and decremented via a MemoryContextCallback when fn_mcxt is deleted. I've adapted the same approach for PL/Python. The main changes are: PLyProcedure now embeds CachedFunction as its first member and is managed by cached_function_compile(). A new PLyProcedureCache struct lives in fn_extra and holds the pointer to PLyProcedure plus SRF state. For cleanup, I use a MemoryContextCallback on fn_mcxt to decrement use_count, and an ExprContextCallback to clean up Python iterator state when the SRF is interrupted. Since fn_extra is now used for PLyProcedureCache, I had to remove the SRF macros and switch to direct isDone signaling via ReturnSetInfo, which is how SQL functions do it anyway. I also fixed the validator to create a fake fcinfo with the correct fn_oid (the function being validated), matching what PL/pgSQL does. Patch attached. -- Matheus Alcantara EDB: https://www.enterprisedb.com
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
plpython: Use funccache.c infrastructure for procedure caching.
- 9bcb8a694b3b 19 (unreleased) landed