I'm considering inventing a new mcxt.c primitive,
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent);
which would have the effect of delinking "context" from its current
parent context and attaching it as a child of the new specified parent.
(Any child contexts that it has would naturally follow along.)
Because of the way that mcxt.c handles parent/child links, there is no
palloc required and so the operation cannot fail.
The use-case that I have for this is to change the status of a memory
context from "temporary" to "permanent". That is, create a context
underneath a transaction-local working context, fill it with stuff
(and/or do other things that might fail), and finally when all is known
good, transfer the context to be a child of CacheMemoryContext. If a
failure happens before that, the context is cleaned up automatically
with no extra effort.
I've spent the past hour or so trying to accomplish the same result by
initially creating the context under CacheMemoryContext and then using
a PG_TRY block to delete it on failure, but that approach is pretty
crufty: it doesn't work nicely when the context has to be passed from
one routine to another, and you end up plastering "volatile" on a lot
of local variables to keep the compiler quiet, and it just seems ugly.
(This is in connection with the long-threatened rewrite of plancache.c:
right now, postgres.c passes a long-lived context to
FastCreateCachedPlan which takes ownership of that, but it has to have
special extra logic to clean up that context on failure, and there is
still a risk of a permanent leak if FastCreateCachedPlan fails partway
through. I'm trying to make that less ugly and more bulletproof.)
Thoughts, objections, bikeshedding?
regards, tom lane
pgsql-hackers by date
|Next:||From: Tom Lane||Date: 2011-09-10 22:21:22|
|Subject: Re: [REVIEW] prepare plans of embedded sql on function start |
|Previous:||From: Andy Colson||Date: 2011-09-10 21:10:19|
|Subject: Re: [REVIEW] prepare plans of embedded sql on function