mirror of https://github.com/postgres/postgres
GUC support. It's now possible to set datestyle, timezone, and client_encoding from postgresql.conf and per-database or per-user settings. Also, implement rollback of SET commands that occur in a transaction that later fails. Create a SET LOCAL var = value syntax that sets the variable only for the duration of the current transaction. All per previous discussions in pghackers.ecpg_big_bison
parent
fa613fa1ea
commit
f0811a74b3
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,136 @@ |
||||
$Header: /cvsroot/pgsql/src/backend/utils/misc/README,v 1.1 2002/05/17 01:19:18 tgl Exp $ |
||||
|
||||
|
||||
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 |
||||
bool assign_hook(newvalue, bool doit, bool interactive) |
||||
where the type of 'newvalue' matches the kind of variable. This function |
||||
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 |
||||
validity of newvalue and not change any derived state. "interactive" is |
||||
true when we are performing a SET command; in this case it is okay for the |
||||
assign_hook to raise an error via elog(). If the function returns false |
||||
for an interactive assignment then guc.c will report a generic "invalid |
||||
value" error message. (An internal elog() in an assign_hook is only |
||||
needed if you want to generate a specialized error message.) But when |
||||
"interactive" is false we are reading a non-interactive option source, |
||||
such as postgresql.conf. In this case the assign_hook should *not* elog |
||||
but should just return false if it doesn't like the newvalue. (An |
||||
elog(LOG) call would be acceptable if you feel a need for a custom |
||||
complaint in this situation.) |
||||
|
||||
For string variables, the signature for assign hooks is a bit different: |
||||
const char *assign_hook(const char *newvalue, |
||||
bool doit, |
||||
bool interactive) |
||||
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 |
||||
datestyle always returns a string that includes both basic datestyle and |
||||
us/euro option, although the input might have specified only one. |
||||
|
||||
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. |
||||
|
||||
To handle these cases we must keep track of as many as four distinct |
||||
values for each variable. They are: |
||||
|
||||
* actual variable contents always the current effective value |
||||
|
||||
* reset_value the value to use for RESET |
||||
|
||||
* session_value the "committed" setting for the session |
||||
|
||||
* tentative_value the uncommitted result of SET |
||||
|
||||
During initialization we set the first three of these (actual, reset_value, |
||||
and session_value) based on whichever non-interactive source has the |
||||
highest priority. All three will have the same value. |
||||
|
||||
A SET LOCAL command sets the actual variable (and nothing else). At |
||||
transaction end, the session_value is used to restore the actual variable |
||||
to its pre-transaction value. |
||||
|
||||
A SET (or SET SESSION) command sets the actual variable, and if no error, |
||||
then sets the tentative_value. If the transaction commits, the |
||||
tentative_value is assigned to the session_value and the actual variable |
||||
(which could by now be different, if the SET was followed by SET LOCAL). |
||||
If the transaction aborts, the tentative_value is discarded and the |
||||
actual variable is restored from the session_value. |
||||
|
||||
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 |
||||
the reset_value also becomes associated with the actual and session values. |
||||
|
||||
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 |
||||
variable, reset_value, and session_value, 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.) |
||||
|
||||
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 |
||||
the source associated with each of the four values. |
||||
|
||||
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. |
||||
|
||||
We allow a variable's actual value, reset_val, session_val, and |
||||
tentative_val to point at the same storage. This makes it slightly harder |
||||
to free space (must test that the value to be freed isn't equal to any of |
||||
the other three pointers). The main advantage is that we never need to |
||||
strdup during transaction commit/abort, so cannot cause an out-of-memory |
||||
failure there. |
File diff suppressed because it is too large
Load Diff
@ -1,18 +1,32 @@ |
||||
/*
|
||||
* Headers for handling of 'SET var TO', 'SHOW var' and 'RESET var' |
||||
* statements |
||||
* variable.h |
||||
* Routines for handling specialized SET variables. |
||||
* |
||||
* $Id: variable.h,v 1.17 2001/11/05 17:46:33 momjian Exp $ |
||||
* $Id: variable.h,v 1.18 2002/05/17 01:19:19 tgl Exp $ |
||||
* |
||||
*/ |
||||
#ifndef VARIABLE_H |
||||
#define VARIABLE_H |
||||
|
||||
extern void SetPGVariable(const char *name, List *args); |
||||
extern void GetPGVariable(const char *name); |
||||
extern void ResetPGVariable(const char *name); |
||||
|
||||
extern void set_default_datestyle(void); |
||||
extern void set_default_client_encoding(void); |
||||
extern const char *assign_datestyle(const char *value, |
||||
bool doit, bool interactive); |
||||
extern const char *show_datestyle(void); |
||||
extern const char *assign_timezone(const char *value, |
||||
bool doit, bool interactive); |
||||
extern const char *show_timezone(void); |
||||
extern const char *assign_XactIsoLevel(const char *value, |
||||
bool doit, bool interactive); |
||||
extern const char *show_XactIsoLevel(void); |
||||
extern bool assign_random_seed(double value, |
||||
bool doit, bool interactive); |
||||
extern const char *show_random_seed(void); |
||||
extern const char *assign_client_encoding(const char *value, |
||||
bool doit, bool interactive); |
||||
extern const char *assign_server_encoding(const char *value, |
||||
bool doit, bool interactive); |
||||
extern const char *show_server_encoding(void); |
||||
extern const char *assign_session_authorization(const char *value, |
||||
bool doit, bool interactive); |
||||
extern const char *show_session_authorization(void); |
||||
|
||||
#endif /* VARIABLE_H */ |
||||
|
Loading…
Reference in new issue