Re: Per-function GUC settings: trickier than it looked

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "Florian G(dot) Pflug" <fgp(at)phlo(dot)org>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Per-function GUC settings: trickier than it looked
Date: 2007-09-03 21:26:23
Message-ID: 26470.1188854783@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

"Florian G. Pflug" <fgp(at)phlo(dot)org> writes:
> And the rule becomes (I tend to forget things, so I like simple
> rules that I can remember ;-) ) "For each SET-clause, there is
> a pseudo-subtransaction affecting only *this* GUC".

The other question is whether we want to change the behavior of SET
LOCAL even in the absence of function SET-clauses. The current rule
is that a LOCAL setting goes away at subtransaction commit, leading
to this behavior:

regression=# show regex_flavor;
regex_flavor
--------------
advanced
(1 row)

regression=# begin;
BEGIN
regression=# savepoint x;
SAVEPOINT
regression=# set local regex_flavor to basic;
SET
regression=# release x;
RELEASE
regression=# show regex_flavor;
regex_flavor
--------------
advanced
(1 row)

which makes some sense if you think of "release" as "subtransaction
end", but not a lot if you think of it as forgetting a savepoint.
Likewise, SET LOCAL within a plpgsql exception block goes away at
successful block exit, which is not the first thing you'd expect.
Neither of these behaviors are documented anywhere AFAIR; certainly
the SET reference page doesn't explain 'em.

I think we should probably take this opportunity to fix that, and
make SET LOCAL mean "persists until end of current top-level
transaction, unless rolled back earlier or within a function SET
clause".

So:

* Plain SET takes effect immediately and persists unless rolled back
or overridden by another explicit SET. In particular the value will
escape out of a function that has a SET-clause for the same variable.

* SET LOCAL takes effect immediately and persists until rolled back,
overridden by another SET, or we exit a function that has a SET-clause
for the same variable.

* Rollback of a transaction or subtransaction cancels any SET or SET
LOCAL within it. Otherwise, the latest un-rolled-back SET or SET LOCAL
determines the active value within a transaction, and the latest
un-rolled-back SET determines the value that will prevail after the
transaction commits.

* A function SET clause saves the entry-time value, and restores it at
function exit, except when overridden by an un-rolled-back SET (but not
SET LOCAL) within the function.

Clear to everyone? Any objections?

As far as implementation, I think this can be made to happen by
rejiggering the value stacking and unstacking rules within guc.c.
I'm tempted to try to get rid of the "tentative" value slots at the
same time. That's a hangover from the pre-subtransaction
implementation, when we only had to remember one inactive value for the
case of SET followed by SET LOCAL within a transaction. Now that we
have a stack of saved values, it seems to make more sense to try to
handle this case by stacking the SET value when we hit SET LOCAL at the
same nesting level.

regards, tom lane

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Gregory Stark 2007-09-03 22:24:20 Re: Hash index todo list item
Previous Message Heikki Linnakangas 2007-09-03 19:42:33 Re: tsearch filenames unlikes special symbols and numbers