diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 9b3c14399c978e83fbf88f4136b3a1a819115a62..893a7b95cdcd457e589c153a2f5f37cdaac50f41 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 581a96caa2623f04740bc6434947caaaf20ddd40..fd13c41a35bd5230229555094fac6f98f3c4b4bb 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -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);
+}
 
 
 /*
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index f5f4a78fe4d3a3bfc943bb96e46524e89efae966..786d696620363d3553341b6e4350861db4e16b01 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 <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);