]> granicus.if.org Git - postgresql/commit
Detoast plpgsql variables if they might live across a transaction boundary.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 16 May 2018 18:56:52 +0000 (14:56 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 16 May 2018 18:56:52 +0000 (14:56 -0400)
commit2efc924180f096070d684a712d6c162b6ae0a5e7
tree40bbfd54bcbef42d8e5d4ddf88ea104f2e70d2a2
parenta11b3bd37f14386310f25e89529bd3de8cd64383
Detoast plpgsql variables if they might live across a transaction boundary.

Up to now, it's been safe for plpgsql to store TOAST pointers in its
variables because the ActiveSnapshot for whatever query called the plpgsql
function will surely protect such TOAST values from being vacuumed away,
even if the owning table rows are committed dead.  With the introduction of
procedures, that assumption is no longer good in "non atomic" executions
of plpgsql code.  We adopt the slightly brute-force solution of detoasting
all TOAST pointers at the time they are stored into variables, if we're in
a non-atomic context, just in case the owning row goes away.

Some care is needed to avoid long-term memory leaks, since plpgsql tends
to run with CurrentMemoryContext pointing to its call-lifespan context,
but we shouldn't assume that no memory is leaked by heap_tuple_fetch_attr.
In plpgsql proper, we can do the detoasting work in the "eval_mcontext".

Most of the code thrashing here is due to the need to add this capability
to expandedrecord.c as well as plpgsql proper.  In expandedrecord.c,
we can't assume that the caller's context is short-lived, so make use of
the short-term sub-context that was already invented for checking domain
constraints.  In view of this repurposing, it seems good to rename that
variable and associated code from "domain_check_cxt" to "short_term_cxt".

Peter Eisentraut and Tom Lane

Discussion: https://postgr.es/m/5AC06865.9050005@anastigmatix.net
src/backend/utils/adt/expandedrecord.c
src/include/postgres.h
src/include/utils/expandedrecord.h
src/pl/plpgsql/src/pl_exec.c
src/test/isolation/expected/plpgsql-toast.out [new file with mode: 0644]
src/test/isolation/isolation_schedule
src/test/isolation/specs/plpgsql-toast.spec [new file with mode: 0644]