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 -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers