From: Tom Lane Date: Wed, 24 Nov 2004 19:51:05 +0000 (+0000) Subject: A client_encoding specification coming from the connection request has X-Git-Tag: REL8_0_0RC1~90 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cf796cc702a879947fd6d1290e25250fe0b37d69;p=postgresql A client_encoding specification coming from the connection request has to be processed by GUC before InitPostgres, because any required lookup of the encoding conversion function has to be done during InitializeClientEncoding. So, I broke this last week by moving GUC processing to after InitPostgres :-(. What we can do as a compromise is process non-SUSET variables during command line scanning (the same as before), and postpone the processing of only SUSET variables. None of the SUSET variables need to be set before InitPostgres. --- diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 9b3c14399c..893a7b95cd 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.438 2004/11/20 00:48:58 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.439 2004/11/24 19:50:59 tgl Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -2205,7 +2205,7 @@ PostgresMain(int argc, char *argv[], const char *username) bool secure; int errs = 0; int debug_flag = -1; /* -1 means not given */ - List *guc_names = NIL; /* for possibly-SUSET options */ + List *guc_names = NIL; /* for SUSET options */ List *guc_values = NIL; GucContext ctx; GucSource gucsource; @@ -2456,8 +2456,15 @@ PostgresMain(int argc, char *argv[], const char *username) /* * s - report usage statistics (timings) after each query + * + * Since log options are SUSET, we need to postpone unless + * still in secure context */ - PendingConfigOption("log_statement_stats", "true"); + if (ctx == PGC_BACKEND) + PendingConfigOption("log_statement_stats", "true"); + else + SetConfigOption("log_statement_stats", "true", + ctx, gucsource); break; case 't': @@ -2490,7 +2497,12 @@ PostgresMain(int argc, char *argv[], const char *username) break; } if (tmp) - PendingConfigOption(tmp, "true"); + { + if (ctx == PGC_BACKEND) + PendingConfigOption(tmp, "true"); + else + SetConfigOption(tmp, "true", ctx, gucsource); + } break; case 'v': @@ -2527,7 +2539,14 @@ PostgresMain(int argc, char *argv[], const char *username) optarg))); } - PendingConfigOption(name, value); + /* + * If a SUSET option, must postpone evaluation, unless + * we are still reading secure switches. + */ + if (ctx == PGC_BACKEND && IsSuperuserConfigOption(name)) + PendingConfigOption(name, value); + else + SetConfigOption(name, value, ctx, gucsource); free(name); if (value) free(value); @@ -2540,6 +2559,32 @@ PostgresMain(int argc, char *argv[], const char *username) } } + /* + * Process any additional GUC variable settings passed in startup + * packet. These are handled exactly like command-line variables. + */ + if (MyProcPort != NULL) + { + ListCell *gucopts = list_head(MyProcPort->guc_options); + + while (gucopts) + { + char *name; + char *value; + + name = lfirst(gucopts); + gucopts = lnext(gucopts); + + value = lfirst(gucopts); + gucopts = lnext(gucopts); + + if (IsSuperuserConfigOption(name)) + PendingConfigOption(name, value); + else + SetConfigOption(name, value, PGC_BACKEND, PGC_S_CLIENT); + } + } + /* Acquire configuration parameters, unless inherited from postmaster */ if (!IsUnderPostmaster) { @@ -2677,10 +2722,8 @@ PostgresMain(int argc, char *argv[], const char *username) SetProcessingMode(NormalProcessing); /* - * Now that we know if client is a superuser, we can apply GUC options - * that came from the client. (For option switches that are definitely - * not SUSET, we just went ahead and applied them above, but anything - * that is or might be SUSET has to be postponed to here.) + * Now that we know if client is a superuser, we can try to apply SUSET + * GUC options that came from the client. */ ctx = am_superuser ? PGC_SUSET : PGC_USERSET; @@ -2703,41 +2746,19 @@ PostgresMain(int argc, char *argv[], const char *username) } } - /* - * Process any additional GUC variable settings passed in startup - * packet. - */ - if (MyProcPort != NULL) - { - ListCell *gucopts = list_head(MyProcPort->guc_options); - - while (gucopts) - { - char *name; - char *value; - - name = lfirst(gucopts); - gucopts = lnext(gucopts); - - value = lfirst(gucopts); - gucopts = lnext(gucopts); - - SetConfigOption(name, value, ctx, PGC_S_CLIENT); - } - - /* - * set up handler to log session end. - */ - if (IsUnderPostmaster && Log_disconnections) - on_proc_exit(log_disconnections, 0); - } - /* * Now all GUC states are fully set up. Report them to client if * appropriate. */ BeginReportingGUCOptions(); + /* + * Also set up handler to log session end; we have to wait till now + * to be sure Log_disconnections has its final value. + */ + if (IsUnderPostmaster && Log_disconnections) + on_proc_exit(log_disconnections, 0); + /* * Send this backend's cancellation info to the frontend. */ diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 581a96caa2..fd13c41a35 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut . * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.249 2004/11/14 19:35:33 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.250 2004/11/24 19:51:03 tgl Exp $ * *-------------------------------------------------------------------- */ @@ -3864,6 +3864,21 @@ GetConfigOptionResetString(const char *name) return NULL; } +/* + * Detect whether the given configuration option can only be set by + * a superuser. + */ +bool +IsSuperuserConfigOption(const char *name) +{ + struct config_generic *record; + + record = find_option(name, ERROR); + /* On an unrecognized name, don't error, just return false. */ + if (record == NULL) + return false; + return (record->context == PGC_SUSET); +} /* diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index f5f4a78fe4..786d696620 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -7,7 +7,7 @@ * Copyright (c) 2000-2004, PostgreSQL Global Development Group * Written by Peter Eisentraut . * - * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.56 2004/11/14 19:35:35 tgl Exp $ + * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.57 2004/11/24 19:51:05 tgl Exp $ *-------------------------------------------------------------------- */ #ifndef GUC_H @@ -44,9 +44,7 @@ * given backend once it's started, but they can vary across backends. * * SUSET options can be set at postmaster startup, with the SIGHUP - * mechanism, or from SQL if you're a superuser. These options cannot - * be set in the connection startup packet, because when it is processed - * we don't yet know if the user is a superuser. + * mechanism, or from SQL if you're a superuser. * * USERSET options can be set by anyone any time. */ @@ -177,6 +175,7 @@ extern void EmitWarningsOnPlaceholders(const char *className); extern const char *GetConfigOption(const char *name); extern const char *GetConfigOptionResetString(const char *name); +extern bool IsSuperuserConfigOption(const char *name); extern void ProcessConfigFile(GucContext context); extern void InitializeGUCOptions(void); extern bool SelectConfigFiles(const char *userDoption, const char *progname);