2007-09-10 02:57:22 +02:00
|
|
|
$PostgreSQL: pgsql/src/backend/utils/misc/README,v 1.6 2007/09/10 00:57:21 tgl Exp $
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
|
|
|
|
GUC IMPLEMENTATION NOTES
|
|
|
|
|
|
|
|
The GUC (Grand Unified Configuration) module implements configuration
|
|
|
|
variables of multiple types (currently boolean, int, float, and string).
|
|
|
|
Variable settings can come from various places, with a priority ordering
|
|
|
|
determining which setting is used.
|
|
|
|
|
|
|
|
|
|
|
|
PER-VARIABLE HOOKS
|
|
|
|
|
|
|
|
Each variable known to GUC can optionally have an assign_hook and/or
|
|
|
|
a show_hook to provide customized behavior. Assign hooks are used to
|
|
|
|
perform validity checking on variable values (above and beyond what
|
|
|
|
GUC can do). They are also used to update any derived state that needs
|
|
|
|
to change when a GUC variable is set. Show hooks are used to modify
|
|
|
|
the default SHOW display for a variable.
|
|
|
|
|
|
|
|
If an assign_hook is provided, it points to a function of the signature
|
2004-01-19 20:04:40 +01:00
|
|
|
bool assign_hook(newvalue, bool doit, GucSource source)
|
|
|
|
where the type of "newvalue" matches the kind of variable. This function
|
2002-05-17 03:19:19 +02:00
|
|
|
is called immediately before actually setting the variable's value (so it
|
|
|
|
can look at the actual variable to determine the old value). If the
|
|
|
|
function returns "true" then the assignment is completed; if it returns
|
|
|
|
"false" then newvalue is considered invalid and the assignment is not
|
|
|
|
performed. If "doit" is false then the function should simply check
|
2004-01-19 20:04:40 +01:00
|
|
|
validity of newvalue and not change any derived state. The "source" parameter
|
|
|
|
indicates where the new value came from. If it is >= PGC_S_INTERACTIVE,
|
|
|
|
then we are performing an interactive assignment (e.g., a SET command).
|
|
|
|
In such cases it is okay for the assign_hook to raise an error via ereport().
|
|
|
|
If the function returns false for an interactive assignment then guc.c will
|
|
|
|
report a generic "invalid value" error message. (An internal ereport() in
|
|
|
|
an assign_hook is only needed if you want to generate a specialized error
|
|
|
|
message.) But when source < PGC_S_INTERACTIVE, we are reading a
|
|
|
|
non-interactive option source, such as postgresql.conf. In this case the
|
|
|
|
assign_hook should *not* ereport but should just return false if it doesn't
|
|
|
|
like the newvalue. (An ereport(LOG) call would be acceptable if you feel a
|
|
|
|
need for a custom complaint in this situation.)
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
For string variables, the signature for assign hooks is a bit different:
|
|
|
|
const char *assign_hook(const char *newvalue,
|
|
|
|
bool doit,
|
2004-01-19 20:04:40 +01:00
|
|
|
GucSource source)
|
2002-05-17 03:19:19 +02:00
|
|
|
The meanings of the parameters are the same as for the other types of GUC
|
|
|
|
variables, but the return value is handled differently:
|
|
|
|
NULL --- assignment fails (like returning false for other datatypes)
|
|
|
|
newvalue --- assignment succeeds, assign the newvalue as-is
|
|
|
|
malloc'd (not palloc'd!!!) string --- assign that value instead
|
|
|
|
The third choice is allowed in case the assign_hook wants to return a
|
|
|
|
"canonical" version of the new value. For example, the assign_hook for
|
2003-07-29 02:03:19 +02:00
|
|
|
datestyle always returns a string that includes both output and input
|
|
|
|
datestyle options, although the input might have specified only one.
|
2002-05-17 03:19:19 +02:00
|
|
|
|
2007-09-10 02:57:22 +02:00
|
|
|
Note that a string variable's assign_hook will NEVER be called with a NULL
|
|
|
|
value for newvalue, since there would be no way to distinguish success
|
|
|
|
and failure returns. If the boot_val or reset_val for a string variable
|
|
|
|
is NULL, it will just be assigned without calling the assign_hook.
|
|
|
|
Therefore, a NULL boot_val should never be used in combination with an
|
|
|
|
assign_hook that has side-effects, as the side-effects wouldn't happen
|
|
|
|
during a RESET that re-institutes the boot-time setting.
|
|
|
|
|
2002-05-17 03:19:19 +02:00
|
|
|
If a show_hook is provided, it points to a function of the signature
|
|
|
|
const char *show_hook(void)
|
|
|
|
This hook allows variable-specific computation of the value displayed
|
|
|
|
by SHOW.
|
|
|
|
|
|
|
|
|
|
|
|
SAVING/RESTORING GUC VARIABLE VALUES
|
|
|
|
|
|
|
|
Prior values of configuration variables must be remembered in order to
|
|
|
|
deal with three special cases: RESET (a/k/a SET TO DEFAULT), rollback of
|
|
|
|
SET on transaction abort, and rollback of SET LOCAL at transaction end
|
|
|
|
(either commit or abort). RESET is defined as selecting the value that
|
|
|
|
would be effective had there never been any SET commands in the current
|
|
|
|
session.
|
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
To handle these cases we must keep track of many distinct values for each
|
|
|
|
variable. The primary values are:
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
* actual variable contents always the current effective value
|
|
|
|
|
|
|
|
* reset_value the value to use for RESET
|
|
|
|
|
|
|
|
* tentative_value the uncommitted result of SET
|
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
The reason we need a tentative_value separate from the actual value is
|
|
|
|
that when a transaction does SET followed by SET LOCAL, the actual value
|
|
|
|
will now be the LOCAL value, but we want to remember the prior SET so that
|
|
|
|
that value is restored at transaction commit.
|
|
|
|
|
|
|
|
In addition, for each level of transaction (possibly nested) we have to
|
|
|
|
remember the transaction-entry-time actual and tentative values, in case
|
|
|
|
we need to restore them at transaction end. (The RESET value is essentially
|
|
|
|
non-transactional, so it doesn't have to be stacked.) For efficiency these
|
|
|
|
stack entries are not constructed until/unless the variable is actually SET
|
|
|
|
within a particular transaction.
|
|
|
|
|
|
|
|
During initialization we set the actual value and reset_value based on
|
|
|
|
whichever non-interactive source has the highest priority. They will
|
|
|
|
have the same value. The tentative_value is not meaningful at this point.
|
|
|
|
|
|
|
|
A SET command starts by stacking the existing actual and tentative values
|
|
|
|
if this hasn't already been done within the current transaction. Then:
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
A SET LOCAL command sets the actual variable (and nothing else). At
|
2004-07-01 02:52:04 +02:00
|
|
|
transaction end, the stacked values are used to restore the GUC entry
|
|
|
|
to its pre-transaction state.
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
A SET (or SET SESSION) command sets the actual variable, and if no error,
|
|
|
|
then sets the tentative_value. If the transaction commits, the
|
2004-07-01 02:52:04 +02:00
|
|
|
tentative_value is assigned again to the actual variable (which could by
|
|
|
|
now be different, if the SET was followed by SET LOCAL). If the
|
|
|
|
transaction aborts, the stacked values are used to restore the GUC entry
|
|
|
|
to its pre-transaction state.
|
|
|
|
|
|
|
|
In the case of SET within nested subtransactions, at each commit the
|
|
|
|
tentative_value propagates out to the next transaction level. It will
|
|
|
|
be thrown away at abort of any level, or after exiting the top transaction.
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
RESET is executed like a SET, but using the reset_value as the desired new
|
|
|
|
value. (We do not provide a RESET LOCAL command, but SET LOCAL TO DEFAULT
|
|
|
|
has the same behavior that RESET LOCAL would.) The source associated with
|
2004-07-01 02:52:04 +02:00
|
|
|
the reset_value also becomes associated with the actual and tentative values.
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
If SIGHUP is received, the GUC code rereads the postgresql.conf
|
|
|
|
configuration file (this does not happen in the signal handler, but at
|
|
|
|
next return to main loop; note that it can be executed while within a
|
|
|
|
transaction). New values from postgresql.conf are assigned to actual
|
2004-07-01 02:52:04 +02:00
|
|
|
variable, reset_value, and stacked actual values, but only if each of
|
|
|
|
these has a current source priority <= PGC_S_FILE. (It is thus possible
|
|
|
|
for reset_value to track the config-file setting even if there is
|
|
|
|
currently a different interactive value of the actual variable.)
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
Note that tentative_value is unused and undefined except between a SET
|
|
|
|
command and the end of the transaction. Also notice that we must track
|
2004-07-01 02:52:04 +02:00
|
|
|
the source associated with each one of the values.
|
2002-05-17 03:19:19 +02:00
|
|
|
|
|
|
|
The assign_hook and show_hook routines work only with the actual variable,
|
|
|
|
and are not directly aware of the additional values maintained by GUC.
|
|
|
|
This is not a problem for normal usage, since we can assign first to the
|
|
|
|
actual variable and then (if that succeeds) to the additional values as
|
|
|
|
needed. However, for SIGHUP rereads we may not want to assign to the
|
|
|
|
actual variable. Our procedure in that case is to call the assign_hook
|
|
|
|
with doit = false so that the value is validated, but no derived state is
|
|
|
|
changed.
|
|
|
|
|
|
|
|
|
|
|
|
STRING MEMORY HANDLING
|
|
|
|
|
|
|
|
String option values are allocated with strdup, not with the
|
|
|
|
pstrdup/palloc mechanisms. We would need to keep them in a permanent
|
|
|
|
context anyway, and strdup gives us more control over handling
|
|
|
|
out-of-memory failures.
|
|
|
|
|
2004-07-01 02:52:04 +02:00
|
|
|
We allow a string variable's actual value, reset_val, tentative_val, and
|
|
|
|
stacked copies of same to point at the same storage. This makes it
|
|
|
|
slightly harder to free space (must test whether a value to be freed isn't
|
|
|
|
equal to any of the other pointers in the GUC entry or associated stack
|
|
|
|
items). The main advantage is that we never need to strdup during
|
|
|
|
transaction commit/abort, so cannot cause an out-of-memory failure there.
|