1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-12 05:01:15 +03:00

Merge the last few variable.c configuration variables into the generic

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.
This commit is contained in:
Tom Lane
2002-05-17 01:19:19 +00:00
parent fa613fa1ea
commit f0811a74b3
42 changed files with 2641 additions and 1802 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.89 2002/04/21 19:48:12 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.90 2002/05/17 01:19:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -3571,11 +3571,17 @@ EncodeInterval(struct tm * tm, fsec_t fsec, int style, char *str)
} /* EncodeInterval() */
void
ClearDateCache(bool dummy)
/* GUC assign_hook for australian_timezones */
bool
ClearDateCache(bool newval, bool doit, bool interactive)
{
int i;
for (i = 0; i < MAXDATEFIELDS; i++)
datecache[i] = NULL;
if (doit)
{
for (i = 0; i < MAXDATEFIELDS; i++)
datecache[i] = NULL;
}
return true;
}

View File

@@ -2,7 +2,7 @@
*
* PostgreSQL locale utilities
*
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.16 2002/04/03 05:39:31 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.17 2002/05/17 01:19:18 tgl Exp $
*
* Portions Copyright (c) 2002, PostgreSQL Global Development Group
*
@@ -10,89 +10,73 @@
*/
#include "postgres.h"
#include "utils/pg_locale.h"
#include <locale.h>
#include "utils/pg_locale.h"
/* GUC storage area */
char * locale_messages;
char * locale_monetary;
char * locale_numeric;
char * locale_time;
char *locale_messages;
char *locale_monetary;
char *locale_numeric;
char *locale_time;
/* GUC parse hooks */
bool locale_messages_check(const char *proposed)
{
#ifdef LC_MESSAGES
return chklocale(LC_MESSAGES, proposed);
#else
/* We return true here so LC_MESSAGES can be set in the
configuration file on every system. */
return true;
#endif
}
bool locale_monetary_check(const char *proposed)
{
return chklocale(LC_MONETARY, proposed);
}
bool locale_numeric_check(const char *proposed)
{
return chklocale(LC_NUMERIC, proposed);
}
bool locale_time_check(const char *proposed)
{
return chklocale(LC_TIME, proposed);
}
/* GUC assign hooks */
void locale_messages_assign(const char *value)
static const char *
locale_xxx_assign(int category, const char *value, bool doit, bool interactive)
{
if (doit)
{
if (!setlocale(category, value))
return NULL;
}
else
{
char *save;
save = setlocale(category, NULL);
if (!save)
return NULL;
if (!setlocale(category, value))
return NULL;
setlocale(category, save);
}
return value;
}
const char *
locale_messages_assign(const char *value, bool doit, bool interactive)
{
/* LC_MESSAGES category does not exist everywhere, but accept it anyway */
#ifdef LC_MESSAGES
setlocale(LC_MESSAGES, value);
return locale_xxx_assign(LC_MESSAGES, value, doit, interactive);
#else
return value;
#endif
}
void locale_monetary_assign(const char *value)
const char *
locale_monetary_assign(const char *value, bool doit, bool interactive)
{
setlocale(LC_MONETARY, value);
return locale_xxx_assign(LC_MONETARY, value, doit, interactive);
}
void locale_numeric_assign(const char *value)
const char *
locale_numeric_assign(const char *value, bool doit, bool interactive)
{
setlocale(LC_NUMERIC, value);
return locale_xxx_assign(LC_NUMERIC, value, doit, interactive);
}
void locale_time_assign(const char *value)
const char *
locale_time_assign(const char *value, bool doit, bool interactive)
{
setlocale(LC_TIME, value);
}
/*
* Returns true if the proposed string represents a valid locale of
* the given category. This is probably pretty slow, but it's not
* called in critical places.
*/
bool
chklocale(int category, const char *proposed)
{
char *save;
save = setlocale(category, NULL);
if (!save)
return false;
if (!setlocale(category, proposed))
return false;
setlocale(category, save);
return true;
return locale_xxx_assign(LC_TIME, value, doit, interactive);
}
@@ -123,7 +107,6 @@ lc_collate_is_c(void)
}
/*
* Return the POSIX lconv struct (contains number/money formatting
* information) with locale information for all categories.
@@ -131,10 +114,11 @@ lc_collate_is_c(void)
struct lconv *
PGLC_localeconv(void)
{
struct lconv *extlconv;
static bool CurrentLocaleConvValid = false;
static struct lconv CurrentLocaleConv;
struct lconv *extlconv;
/* Did we do it already? */
if (CurrentLocaleConvValid)
return &CurrentLocaleConv;

View File

@@ -3,7 +3,7 @@
* back to source text
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.104 2002/05/12 23:43:03 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.105 2002/05/17 01:19:18 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -2576,27 +2576,33 @@ quote_identifier(const char *ident)
* and contains only lowercase letters, digits, and underscores, *and* is
* not any SQL keyword. Otherwise, supply quotes.
*/
int nquotes = 0;
bool safe;
const char *ptr;
char *result;
char *optr;
/*
* would like to use <ctype.h> macros here, but they might yield
* unwanted locale-specific results...
*/
safe = ((ident[0] >= 'a' && ident[0] <= 'z') || ident[0] == '_');
if (safe)
for (ptr = ident; *ptr; ptr++)
{
const char *ptr;
char ch = *ptr;
for (ptr = ident + 1; *ptr; ptr++)
if ((ch >= 'a' && ch <= 'z') ||
(ch >= '0' && ch <= '9') ||
(ch == '_'))
{
char ch = *ptr;
safe = ((ch >= 'a' && ch <= 'z') ||
(ch >= '0' && ch <= '9') ||
(ch == '_'));
if (!safe)
break;
/* okay */
}
else
{
safe = false;
if (ch == '"')
nquotes++;
}
}
@@ -2618,8 +2624,21 @@ quote_identifier(const char *ident)
if (safe)
return ident; /* no change needed */
result = (char *) palloc(strlen(ident) + 2 + 1);
sprintf(result, "\"%s\"", ident);
result = (char *) palloc(strlen(ident) + nquotes + 2 + 1);
optr = result;
*optr++ = '"';
for (ptr = ident; *ptr; ptr++)
{
char ch = *ptr;
if (ch == '"')
*optr++ = '"';
*optr++ = ch;
}
*optr++ = '"';
*optr = '\0';
return result;
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.97 2002/05/05 00:03:29 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.98 2002/05/17 01:19:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -841,105 +841,68 @@ elog_message_prefix(int lev)
/*
* GUC support routines
*/
bool
check_server_min_messages(const char *lev)
const char *
assign_server_min_messages(const char *newval,
bool doit, bool interactive)
{
if (strcasecmp(lev, "debug") == 0 ||
strcasecmp(lev, "debug5") == 0 ||
strcasecmp(lev, "debug4") == 0 ||
strcasecmp(lev, "debug3") == 0 ||
strcasecmp(lev, "debug2") == 0 ||
strcasecmp(lev, "debug1") == 0 ||
strcasecmp(lev, "info") == 0 ||
strcasecmp(lev, "notice") == 0 ||
strcasecmp(lev, "warning") == 0 ||
strcasecmp(lev, "error") == 0 ||
strcasecmp(lev, "log") == 0 ||
strcasecmp(lev, "fatal") == 0 ||
strcasecmp(lev, "panic") == 0)
return true;
return false;
}
void
assign_server_min_messages(const char *lev)
{
if (strcasecmp(lev, "debug") == 0)
server_min_messages = DEBUG5;
else if (strcasecmp(lev, "debug5") == 0)
server_min_messages = DEBUG5;
else if (strcasecmp(lev, "debug4") == 0)
server_min_messages = DEBUG4;
else if (strcasecmp(lev, "debug3") == 0)
server_min_messages = DEBUG3;
else if (strcasecmp(lev, "debug2") == 0)
server_min_messages = DEBUG2;
else if (strcasecmp(lev, "debug1") == 0)
server_min_messages = DEBUG1;
else if (strcasecmp(lev, "info") == 0)
server_min_messages = INFO;
else if (strcasecmp(lev, "notice") == 0)
server_min_messages = NOTICE;
else if (strcasecmp(lev, "warning") == 0)
server_min_messages = WARNING;
else if (strcasecmp(lev, "error") == 0)
server_min_messages = ERROR;
else if (strcasecmp(lev, "log") == 0)
server_min_messages = LOG;
else if (strcasecmp(lev, "fatal") == 0)
server_min_messages = FATAL;
else if (strcasecmp(lev, "panic") == 0)
server_min_messages = PANIC;
if (strcasecmp(newval, "debug") == 0)
{ if (doit) server_min_messages = DEBUG1; }
else if (strcasecmp(newval, "debug5") == 0)
{ if (doit) server_min_messages = DEBUG5; }
else if (strcasecmp(newval, "debug4") == 0)
{ if (doit) server_min_messages = DEBUG4; }
else if (strcasecmp(newval, "debug3") == 0)
{ if (doit) server_min_messages = DEBUG3; }
else if (strcasecmp(newval, "debug2") == 0)
{ if (doit) server_min_messages = DEBUG2; }
else if (strcasecmp(newval, "debug1") == 0)
{ if (doit) server_min_messages = DEBUG1; }
else if (strcasecmp(newval, "info") == 0)
{ if (doit) server_min_messages = INFO; }
else if (strcasecmp(newval, "notice") == 0)
{ if (doit) server_min_messages = NOTICE; }
else if (strcasecmp(newval, "warning") == 0)
{ if (doit) server_min_messages = WARNING; }
else if (strcasecmp(newval, "error") == 0)
{ if (doit) server_min_messages = ERROR; }
else if (strcasecmp(newval, "log") == 0)
{ if (doit) server_min_messages = LOG; }
else if (strcasecmp(newval, "fatal") == 0)
{ if (doit) server_min_messages = FATAL; }
else if (strcasecmp(newval, "panic") == 0)
{ if (doit) server_min_messages = PANIC; }
else
/* Can't get here unless guc.c screwed up */
elog(ERROR, "bogus server_min_messages %s", lev);
return NULL; /* fail */
return newval; /* OK */
}
bool
check_client_min_messages(const char *lev)
const char *
assign_client_min_messages(const char *newval,
bool doit, bool interactive)
{
if (strcasecmp(lev, "debug") == 0 ||
strcasecmp(lev, "debug5") == 0 ||
strcasecmp(lev, "debug4") == 0 ||
strcasecmp(lev, "debug3") == 0 ||
strcasecmp(lev, "debug2") == 0 ||
strcasecmp(lev, "debug1") == 0 ||
strcasecmp(lev, "log") == 0 ||
strcasecmp(lev, "info") == 0 ||
strcasecmp(lev, "notice") == 0 ||
strcasecmp(lev, "warning") == 0 ||
strcasecmp(lev, "error") == 0)
return true;
return false;
}
void
assign_client_min_messages(const char *lev)
{
if (strcasecmp(lev, "debug") == 0)
client_min_messages = DEBUG5;
else if (strcasecmp(lev, "debug5") == 0)
client_min_messages = DEBUG5;
else if (strcasecmp(lev, "debug4") == 0)
client_min_messages = DEBUG4;
else if (strcasecmp(lev, "debug3") == 0)
client_min_messages = DEBUG3;
else if (strcasecmp(lev, "debug2") == 0)
client_min_messages = DEBUG2;
else if (strcasecmp(lev, "debug1") == 0)
client_min_messages = DEBUG1;
else if (strcasecmp(lev, "log") == 0)
client_min_messages = LOG;
else if (strcasecmp(lev, "info") == 0)
client_min_messages = INFO;
else if (strcasecmp(lev, "notice") == 0)
client_min_messages = NOTICE;
else if (strcasecmp(lev, "warning") == 0)
client_min_messages = WARNING;
else if (strcasecmp(lev, "error") == 0)
client_min_messages = ERROR;
if (strcasecmp(newval, "debug") == 0)
{ if (doit) client_min_messages = DEBUG1; }
else if (strcasecmp(newval, "debug5") == 0)
{ if (doit) client_min_messages = DEBUG5; }
else if (strcasecmp(newval, "debug4") == 0)
{ if (doit) client_min_messages = DEBUG4; }
else if (strcasecmp(newval, "debug3") == 0)
{ if (doit) client_min_messages = DEBUG3; }
else if (strcasecmp(newval, "debug2") == 0)
{ if (doit) client_min_messages = DEBUG2; }
else if (strcasecmp(newval, "debug1") == 0)
{ if (doit) client_min_messages = DEBUG1; }
else if (strcasecmp(newval, "log") == 0)
{ if (doit) client_min_messages = LOG; }
else if (strcasecmp(newval, "info") == 0)
{ if (doit) client_min_messages = INFO; }
else if (strcasecmp(newval, "notice") == 0)
{ if (doit) client_min_messages = NOTICE; }
else if (strcasecmp(newval, "warning") == 0)
{ if (doit) client_min_messages = WARNING; }
else if (strcasecmp(newval, "error") == 0)
{ if (doit) client_min_messages = ERROR; }
else
/* Can't get here unless guc.c screwed up */
elog(ERROR, "bogus client_min_messages %s", lev);
return NULL; /* fail */
return newval; /* OK */
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.90 2002/05/06 19:47:30 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.91 2002/05/17 01:19:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -614,6 +614,9 @@ InitializeSessionUserId(const char *username)
SetSessionUserId(usesysid); /* sets CurrentUserId too */
/* Record username as a config option too */
SetConfigOption("session_authorization", username,
PGC_BACKEND, PGC_S_OVERRIDE);
/*
* Set up user-specific configuration variables. This is a good
@@ -653,23 +656,16 @@ InitializeSessionUserIdStandalone(void)
* Change session auth ID while running
*
* Only a superuser may set auth ID to something other than himself.
*
* username == NULL implies reset to default (AuthenticatedUserId).
*/
void
SetSessionAuthorization(const char *username)
SetSessionAuthorization(Oid userid)
{
Oid userid;
/* Must have authenticated already, else can't make permission check */
AssertState(OidIsValid(AuthenticatedUserId));
if (username == NULL)
userid = AuthenticatedUserId;
else
{
userid = get_usesysid(username);
if (userid != AuthenticatedUserId &&
!AuthenticatedUserIsSuperuser)
elog(ERROR, "permission denied");
}
if (userid != AuthenticatedUserId &&
!AuthenticatedUserIsSuperuser)
elog(ERROR, "permission denied");
SetSessionUserId(userid);
SetUserId(userid);

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.104 2002/05/05 00:03:29 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.105 2002/05/17 01:19:18 tgl Exp $
*
*
*-------------------------------------------------------------------------
@@ -28,7 +28,6 @@
#include "catalog/pg_database.h"
#include "catalog/pg_shadow.h"
#include "commands/trigger.h"
#include "commands/variable.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "storage/backendid.h"
@@ -132,6 +131,9 @@ ReverifyMyDatabase(const char *name)
*/
#ifdef MULTIBYTE
SetDatabaseEncoding(dbform->encoding);
/* If we have no other source of client_encoding, use server encoding */
SetConfigOption("client_encoding", GetDatabaseEncodingName(),
PGC_BACKEND, PGC_S_DEFAULT);
#else
if (dbform->encoding != PG_SQL_ASCII)
elog(FATAL, "database was initialized with MULTIBYTE encoding %d,\n\tbut the backend was compiled without multibyte support.\n\tlooks like you need to initdb or recompile.",
@@ -388,11 +390,6 @@ InitPostgres(const char *dbname, const char *username)
/* set default namespace search path */
InitializeSearchPath();
#ifdef MULTIBYTE
/* set default client encoding --- uses info from ReverifyMyDatabase */
set_default_client_encoding();
#endif
/*
* Set up process-exit callback to do pre-shutdown cleanup. This should
* be last because we want shmem_exit to call this routine before the exit

View File

@@ -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.

View File

@@ -4,7 +4,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc-file.l,v 1.11 2002/03/02 21:39:33 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc-file.l,v 1.12 2002/05/17 01:19:18 tgl Exp $
*/
%{
@@ -168,7 +168,7 @@ ProcessConfigFile(GucContext context)
head = tail = NULL;
opt_name = opt_value = NULL;
while((token = yylex()))
while ((token = yylex()))
switch(parse_state)
{
case 0: /* no previous input */
@@ -188,23 +188,22 @@ ProcessConfigFile(GucContext context)
token = yylex();
if (token != GUC_ID && token != GUC_STRING &&
token != GUC_INTEGER && token != GUC_REAL &&
token != GUC_UNQUOTED_STRING)
token != GUC_INTEGER && token != GUC_REAL &&
token != GUC_UNQUOTED_STRING)
goto parse_error;
opt_value = strdup(yytext);
if (opt_value == NULL)
goto out_of_memory;
if (token == GUC_STRING)
{
/* remove the beginning and ending quote/apostrophe */
/* first: shift the whole shooting match down one
character */
memmove(opt_value,opt_value+1,strlen(opt_value)-1);
/* second: null out the 2 characters we shifted */
opt_value[strlen(opt_value)-2]='\0';
/* do the escape thing. free()'s the strdup above */
opt_value=GUC_scanstr(opt_value);
}
if (token == GUC_STRING)
{
/* remove the beginning and ending quote/apostrophe */
/* first: shift the whole thing down one character */
memmove(opt_value,opt_value+1,strlen(opt_value)-1);
/* second: null out the 2 characters we shifted */
opt_value[strlen(opt_value)-2]='\0';
/* do the escape thing. free()'s the strdup above */
opt_value=GUC_scanstr(opt_value);
}
parse_state = 2;
break;
@@ -241,14 +240,14 @@ ProcessConfigFile(GucContext context)
for(item = head; item; item=item->next)
{
if (!set_config_option(item->name, item->value, context,
false, PGC_S_INFINITY))
PGC_S_FILE, false, false))
goto cleanup_exit;
}
/* If we got here all the options parsed okay. */
for(item = head; item; item=item->next)
set_config_option(item->name, item->value, context,
true, PGC_S_FILE);
PGC_S_FILE, false, true);
cleanup_exit:
free_name_value_list(head);

File diff suppressed because it is too large Load Diff

View File

@@ -192,7 +192,10 @@
#
#dynamic_library_path = '$libdir'
#search_path = '$user,public'
#datestyle = 'iso, us'
#timezone = unknown # actually, defaults to TZ environment setting
#australian_timezones = false
#client_encoding = sql_ascii # actually, defaults to database encoding
#authentication_timeout = 60 # min 1, max 600
#deadlock_timeout = 1000
#default_transaction_isolation = 'read committed'