Robert Haas <[email protected]> writes:
> Another idea is to just keep track of which contexts need to be
> deleted if we error out. Let's say that when we create a temporary
> check-hook context, we add it to a linked list, similar to
> guc_stack_list, but each element of the list is just a memory context
> pointer and the current GUCNestLevel. When AtEOXact_GUC is called,
> after doing the stuff it does today, it can iterate over this new list
> and filter on nestLevel. Entries that need to get blown away are
> subjected to MemoryContextDelete() and also deleted from the list.

I think something like this could work, but you'd have to be careful
about how you manage the list: you can't just palloc something, nor
lappend it to a list, for fear of OOM right there.  An slist or dlist
removes the lappend hazard, but you still need storage to hold the
list entry.

One way could be to allocate the list entry inside the new
as-yet-transient context, expecting that there's guaranteed to be
enough space in it for that to work.  (If guc.c controls the
initial parameters for the new context, that's a safe assumption.)
The downside to this is that the check_hook could not be allowed
to reset the context ... but it's hard to see why it'd need to.

Alternatively: I don't see any really good reason for a check_hook
to be setting other GUCs, in fact it's probably a seriously bad idea.
(It's a *check* hook, it's not supposed to be causing any
side-effects.)  Therefore, there can be at most one of these
operations in flight at a time, so you don't need any dynamic data
structure.  A simple static variable remembering a not-yet-reparented
context would do it.

                        regards, tom lane


Reply via email to