]> granicus.if.org Git - postgresql/commitdiff
A client_encoding specification coming from the connection request has
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 24 Nov 2004 19:51:05 +0000 (19:51 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 24 Nov 2004 19:51:05 +0000 (19:51 +0000)
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.

src/backend/tcop/postgres.c
src/backend/utils/misc/guc.c
src/include/utils/guc.h

index 9b3c14399c978e83fbf88f4136b3a1a819115a62..893a7b95cdcd457e589c153a2f5f37cdaac50f41 100644 (file)
@@ -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.
         */
index 581a96caa2623f04740bc6434947caaaf20ddd40..fd13c41a35bd5230229555094fac6f98f3c4b4bb 100644 (file)
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * 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);
+}
 
 
 /*
index f5f4a78fe4d3a3bfc943bb96e46524e89efae966..786d696620363d3553341b6e4350861db4e16b01 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (c) 2000-2004, PostgreSQL Global Development Group
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
- * $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);