diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l
index a0044abc86..463b5541b3 100644
--- a/src/backend/utils/misc/guc-file.l
+++ b/src/backend/utils/misc/guc-file.l
@@ -4,7 +4,7 @@
  *
  * Copyright (c) 2000-2006, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.44 2006/08/13 02:22:24 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.45 2006/08/14 02:27:26 momjian Exp $
  */
 
 %{
@@ -50,8 +50,7 @@ int GUC_yylex(void);
 static bool ParseConfigFile(const char *config_file, const char *calling_file,
 							int depth, GucContext context, int elevel,
 							struct name_value_pair **head_p,
-							struct name_value_pair **tail_p,
-							int *varcount);
+							struct name_value_pair **tail_p);
 static void free_name_value_list(struct name_value_pair * list);
 static char *GUC_scanstr(const char *s);
 
@@ -115,11 +114,8 @@ STRING          \'([^'\\\n]|\\.|\'\')*\'
 void
 ProcessConfigFile(GucContext context)
 {
-	int			elevel, i;
+	int			elevel;
 	struct name_value_pair *item, *head, *tail;
-	char	   *env;
-	bool	   *apply_list = NULL;
-	int			varcount = 0;
 
 	Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
 
@@ -138,109 +134,25 @@ ProcessConfigFile(GucContext context)
 
 	if (!ParseConfigFile(ConfigFileName, NULL,
 						 0, context, elevel,
-						 &head, &tail, &varcount))
+						 &head, &tail))
 		goto cleanup_list;
 
-	/* Can we allocate memory here, what about leaving here prematurely? */
-	apply_list = (bool *) palloc(sizeof(bool) * varcount);
-
 	/* Check if all options are valid */
-	for (item = head, i = 0; item; item = item->next, i++)
+	for (item = head; item; item = item->next)
 	{
-		bool isEqual, isContextOk;
-
-		if (!verify_config_option(item->name, item->value, context,
-						  PGC_S_FILE, &isEqual, &isContextOk))
-		{
-			ereport(elevel,
-				(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
-				errmsg("configuration file is invalid")));
+		if (!set_config_option(item->name, item->value, context,
+							   PGC_S_FILE, false, false))
 			goto cleanup_list;
-		}
-
-		if (isContextOk == false)
-		{
-			apply_list[i] = false;
-			if (context == PGC_SIGHUP)
-			{
-				if (isEqual == false)
-					ereport(elevel,
-						(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
-						errmsg("parameter \"%s\" cannot be changed after server start; configuration file change ignored",
-						item->name)));
-			}
-			else
-				/* if it is boot phase, context must be valid for all
-				 * configuration item. */
-				goto cleanup_list;
-		}
-		else
-			apply_list[i] = true;
 	}
 
 	/* If we got here all the options checked out okay, so apply them. */
-	for (item = head, i = 0; item; item = item->next, i++)
-		if (apply_list[i])
-			set_config_option(item->name, item->value, context,
-							  PGC_S_FILE, false, true);
-
-	if (context == PGC_SIGHUP)
+	for (item = head; item; item = item->next)
 	{
-	/*
-	 * Revert all "untouched" options with reset source PGC_S_FILE to
-	 * default/boot value.
-	 */
-		for (i = 0; i < num_guc_variables; i++)
-		{
-			struct config_generic *gconf = guc_variables[i];
-
-			if (gconf->reset_source == PGC_S_FILE &&
-				 !(gconf->status & GUC_IN_CONFFILE))
-			{
-				if (gconf->context == PGC_BACKEND && IsUnderPostmaster)
-					; /* Be silent. Does any body want message from each session? */
-				else if (gconf->context == PGC_POSTMASTER)
-					ereport(elevel,
-						(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
-						errmsg("parameter \"%s\" cannot be changed (commented) after server start; configuration file change ignored",
-						gconf->name)));
-				else if (set_config_option(gconf->name, NULL, context,
-										   PGC_S_FILE, false, true))
-				{
-					GucStack   *stack;
-
-					gconf->reset_source = PGC_S_DEFAULT;
-
-					for (stack = gconf->stack; stack; stack = stack->prev)
-						if (stack->source == PGC_S_FILE)
-							stack->source = PGC_S_DEFAULT;
-
-					ereport(elevel,
-							(errcode(ERRCODE_SUCCESSFUL_COMPLETION),
-							errmsg("configuration option %s returned to default value", gconf->name)));
-				}
-			}
-			gconf->status &= ~GUC_IN_CONFFILE;
-		}
-
-		/*
-		 * Revert to environment variable. PGPORT is ignored, because it cannot be
-		 * set in running state.
-		 */
-		env = getenv("PGDATESTYLE");
-		if (env != NULL)
-			set_config_option("datestyle", env, context,
-							  PGC_S_ENV_VAR, false, true);
-
-		env = getenv("PGCLIENTENCODING");
-		if (env != NULL)
-			set_config_option("client_encoding", env, context,
-							PGC_S_ENV_VAR, false, true);
+		set_config_option(item->name, item->value, context,
+						  PGC_S_FILE, false, true);
 	}
 
-cleanup_list:
-	if (apply_list)
-		pfree(apply_list);
+ cleanup_list:
 	free_name_value_list(head);
 }
 
@@ -277,14 +189,13 @@ static bool
 ParseConfigFile(const char *config_file, const char *calling_file,
 				int depth, GucContext context, int elevel,
 				struct name_value_pair **head_p,
-				struct name_value_pair **tail_p,
-				int *varcount)
+				struct name_value_pair **tail_p)
 {
-	bool			OK = true;
-	char			abs_path[MAXPGPATH];
-	FILE		   *fp;
+	bool		OK = true;
+	char		abs_path[MAXPGPATH];
+	FILE	   *fp;
 	YY_BUFFER_STATE lex_buffer;
-	int				token;
+	int			token;
 
 	/*
 	 * Reject too-deep include nesting depth.  This is just a safety check
@@ -378,7 +289,7 @@ ParseConfigFile(const char *config_file, const char *calling_file,
 
 			if (!ParseConfigFile(opt_value, config_file,
 								 depth + 1, context, elevel,
-								 head_p, tail_p, varcount))
+								 head_p, tail_p))
 			{
 				pfree(opt_name);
 				pfree(opt_value);
@@ -422,7 +333,6 @@ ParseConfigFile(const char *config_file, const char *calling_file,
 			else
 				(*tail_p)->next = item;
 			*tail_p = item;
-			(*varcount)++;
 		}
 
 		/* break out of loop if read EOF, else loop for next line */
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index cda5a41142..0e16035ef6 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.340 2006/08/13 15:37:02 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.341 2006/08/14 02:27:26 momjian Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -2313,7 +2313,7 @@ guc_strdup(int elevel, const char *src)
  * states).
  */
 static void
-set_string_field(struct config_string *conf, char **field, char *newval)
+set_string_field(struct config_string * conf, char **field, char *newval)
 {
 	char	   *oldval = *field;
 	GucStack   *stack;
@@ -2535,7 +2535,8 @@ add_placeholder_variable(const char *name, int elevel)
 	gen = &var->gen;
 	memset(var, 0, sz);
 
-	if ((gen->name = guc_strdup(elevel, name)) == NULL)
+	gen->name = guc_strdup(elevel, name);
+	if (gen->name == NULL)
 	{
 		free(var);
 		return NULL;
@@ -2692,40 +2693,40 @@ InitializeGUCOptions(void)
 				{
 					struct config_bool *conf = (struct config_bool *) gconf;
 
-					if (conf->assign_hook &&
-						!(*conf->assign_hook) (conf->boot_val, true,
-												PGC_S_DEFAULT))
-						elog(FATAL, "failed to initialize %s to %d",
-							 conf->gen.name, (int) conf->boot_val);
-					*conf->variable = conf->reset_val = conf->boot_val;
+					if (conf->assign_hook)
+						if (!(*conf->assign_hook) (conf->reset_val, true,
+												   PGC_S_DEFAULT))
+							elog(FATAL, "failed to initialize %s to %d",
+								 conf->gen.name, (int) conf->reset_val);
+					*conf->variable = conf->reset_val;
 					break;
 				}
 			case PGC_INT:
 				{
 					struct config_int *conf = (struct config_int *) gconf;
 
-					Assert(conf->boot_val >= conf->min);
-					Assert(conf->boot_val <= conf->max);
-					if (conf->assign_hook &&
-						!(*conf->assign_hook) (conf->boot_val, true,
-												PGC_S_DEFAULT))
-						elog(FATAL, "failed to initialize %s to %d",
-							 conf->gen.name, conf->boot_val);
-					*conf->variable = conf->reset_val = conf->boot_val; 
+					Assert(conf->reset_val >= conf->min);
+					Assert(conf->reset_val <= conf->max);
+					if (conf->assign_hook)
+						if (!(*conf->assign_hook) (conf->reset_val, true,
+												   PGC_S_DEFAULT))
+							elog(FATAL, "failed to initialize %s to %d",
+								 conf->gen.name, conf->reset_val);
+					*conf->variable = conf->reset_val;
 					break;
 				}
 			case PGC_REAL:
 				{
 					struct config_real *conf = (struct config_real *) gconf;
 
-					Assert(conf->boot_val >= conf->min);
-					Assert(conf->boot_val <= conf->max);
-					if (conf->assign_hook &&
-						!(*conf->assign_hook) (conf->boot_val, true,
-											   PGC_S_DEFAULT))
-						elog(FATAL, "failed to initialize %s to %g",
-							 conf->gen.name, conf->boot_val);
-					*conf->variable = conf->reset_val = conf->boot_val; 
+					Assert(conf->reset_val >= conf->min);
+					Assert(conf->reset_val <= conf->max);
+					if (conf->assign_hook)
+						if (!(*conf->assign_hook) (conf->reset_val, true,
+												   PGC_S_DEFAULT))
+							elog(FATAL, "failed to initialize %s to %g",
+								 conf->gen.name, conf->reset_val);
+					*conf->variable = conf->reset_val;
 					break;
 				}
 			case PGC_STRING:
@@ -2738,8 +2739,10 @@ InitializeGUCOptions(void)
 					conf->tentative_val = NULL;
 
 					if (conf->boot_val == NULL)
+					{
 						/* Cannot set value yet */
 						break;
+					}
 
 					str = guc_strdup(FATAL, conf->boot_val);
 					conf->reset_val = str;
@@ -2751,8 +2754,10 @@ InitializeGUCOptions(void)
 						newstr = (*conf->assign_hook) (str, true,
 													   PGC_S_DEFAULT);
 						if (newstr == NULL)
+						{
 							elog(FATAL, "failed to initialize %s to \"%s\"",
 								 conf->gen.name, str);
+						}
 						else if (newstr != str)
 						{
 							free(str);
@@ -2792,10 +2797,12 @@ InitializeGUCOptions(void)
 	if (env != NULL)
 		SetConfigOption("port", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
 
-	if ((env = getenv("PGDATESTYLE")) != NULL)
+	env = getenv("PGDATESTYLE");
+	if (env != NULL)
 		SetConfigOption("datestyle", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
 
-	if ((env = getenv("PGCLIENTENCODING")) != NULL)
+	env = getenv("PGCLIENTENCODING");
+	if (env != NULL)
 		SetConfigOption("client_encoding", env, PGC_POSTMASTER, PGC_S_ENV_VAR);
 }
 
@@ -3172,7 +3179,7 @@ AtEOXact_GUC(bool isCommit, bool isSubXact)
 	for (i = 0; i < num_guc_variables; i++)
 	{
 		struct config_generic *gconf = guc_variables[i];
-		int			my_status = gconf->status & (~GUC_IN_CONFFILE);
+		int			my_status = gconf->status;
 		GucStack   *stack = gconf->stack;
 		bool		useTentative;
 		bool		changed;
@@ -3683,422 +3690,6 @@ call_string_assign_hook(GucStringAssignHook assign_hook,
 	return result;
 }
 
-/*
- * Try to parse value. Determine what is type and call related
- * parsing function or if newval is equal to NULL, reset value 
- * to default or bootval. If the value parsed okay return true,
- * else false.
- */
-static bool
-parse_value(int elevel, const struct config_generic *record, 
-		const char *value, GucSource *source, bool changeVal, 
-		union config_var_value *retval)
-{
-	/*
-	 * Evaluate value and set variable.
-	 */
-	switch (record->vartype)
-	{
-		case PGC_BOOL:
-			{
-				struct config_bool *conf = (struct config_bool *) record;
-				bool		newval;
-
-				if (value)
-				{
-					if (!parse_bool(value, &newval))
-					{
-						ereport(elevel,
-								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-						  errmsg("parameter \"%s\" requires a Boolean value",
-								 record->name)));
-						return false;
-					}
-				}
-				else
-				{
-					/*
-					 * Revert value to default if source is configuration file. It is used when
-					 * configuration parameter is removed/commented out in the config file. Else
-					 * RESET or SET TO DEFAULT command is called and reset_val is used.
-					 */
-					if (*source == PGC_S_FILE)
-						newval =  conf->boot_val;
-					else
-					{
-						newval = conf->reset_val;
-						*source = conf->gen.reset_source;
-					}
-				}
-
-				if (conf->assign_hook &&
-					!(*conf->assign_hook) (newval, changeVal, *source))
-					{
-						ereport(elevel,
-								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-							 errmsg("invalid value for parameter \"%s\": %d",
-									record->name, (int) newval)));
-						return false;
-					}
-				if (retval)
-					retval->boolval = newval;
-				break;
-			}
-
-		case PGC_INT:
-			{
-				struct config_int *conf = (struct config_int *) record;
-				int			newval;
-
-				if (value)
-				{
-					if (!parse_int(value, &newval, conf->gen.flags))
-					{
-						ereport(elevel,
-								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-						 errmsg("parameter \"%s\" requires an integer value",
-								record->name)));
-						return false;
-					}
-					if (newval < conf->min || newval > conf->max)
-					{
-						ereport(elevel,
-								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-								 errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
-										newval, record->name, conf->min, conf->max)));
-						return false;
-					}
-				}
-				else
-				{
-					/*
-					 * Revert value to default if source is configuration file. It is used when
-					 * configuration parameter is removed/commented out in the config file. Else
-					 * RESET or SET TO DEFAULT command is called and reset_val is used.
-					 */
-					if (*source == PGC_S_FILE)
-						newval =  conf->boot_val;
-					else
-					{
-						newval = conf->reset_val;
-						*source = conf->gen.reset_source;
-					}
-				}
-
-				if (conf->assign_hook)
-					if (!(*conf->assign_hook) (newval, changeVal, *source))
-					{
-						ereport(elevel,
-								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-							 errmsg("invalid value for parameter \"%s\": %d",
-									record->name, newval)));
-						return false;
-					}
-				if (retval)
-					retval->intval = newval;
-				break;
-			}
-
-		case PGC_REAL:
-			{
-				struct config_real *conf = (struct config_real *) record;
-				double		newval;
-
-				if (value)
-				{
-					if (!parse_real(value, &newval))
-					{
-						ereport(elevel,
-								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-						  errmsg("parameter \"%s\" requires a numeric value",
-								 record->name)));
-						return false;
-					}
-					if (newval < conf->min || newval > conf->max)
-					{
-						ereport(elevel,
-								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-								 errmsg("%g is outside the valid range for parameter \"%s\" (%g .. %g)",
-										newval, record->name, conf->min, conf->max)));
-						return false;
-					}
-				}
-				else
-				{
-					/*
-					 * Revert value to default if source is configuration file. It is used when
-					 * configuration parameter is removed/commented out in the config file. Else
-					 * RESET or SET TO DEFAULT command is called and reset_val is used.
-					 */
-					if (*source == PGC_S_FILE)
-						newval =  conf->boot_val;
-					else
-					{
-						newval = conf->reset_val;
-						*source = conf->gen.reset_source;
-					}
-				}
-
-				if (conf->assign_hook &&
-					!(*conf->assign_hook) (newval, changeVal, *source))
-					{
-						ereport(elevel,
-								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-							 errmsg("invalid value for parameter \"%s\": %g",
-									record->name, newval)));
-						return false;
-					}
-				if (retval)
-					retval->realval = newval;
-				break;
-			}
-
-		case PGC_STRING:
-			{
-				struct config_string *conf = (struct config_string *) record;
-				char	   *newval;
-
-				if (value)
-				{
-					if ((newval = guc_strdup(elevel, value)) == NULL)
-						return false;
-					/*
-					 * The only sort of "parsing" check we need to do is
-					 * apply truncation if GUC_IS_NAME.
-					 */
-					if (conf->gen.flags & GUC_IS_NAME)
-						truncate_identifier(newval, strlen(newval), true);
-				}
-				else if (*source == PGC_S_FILE)
-				{
-					/* Revert value to default when item is removed from config file. */
-					if (conf->boot_val != NULL)
-					{
-						newval = guc_strdup(elevel, conf->boot_val);
-						if (newval == NULL)
-							return false;
-					}
-					else
-						return false;
-				} 
-				else if (conf->reset_val)
-				{
-					/*
-					 * We could possibly avoid strdup here, but easier to make
-					 * this case work the same as the normal assignment case.
-					 */
-					if ((newval = guc_strdup(elevel, conf->reset_val)) == NULL)
-						return false;
-					*source = conf->gen.reset_source;
-				}
-				else
-					/* Nothing to reset to, as yet; so do nothing */
-					break;
-
-				if (conf->assign_hook)
-				{
-					const char *hookresult;
-
-					/*
-					 * If the hook ereports, we have to make sure we free
-					 * newval, else it will be a permanent memory leak.
-					 */
-					hookresult = call_string_assign_hook(conf->assign_hook,
-														 newval,
-														 changeVal,
-														 *source);
-					if (hookresult == NULL)
-					{
-						free(newval);
-						ereport(elevel,
-								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-						 errmsg("invalid value for parameter \"%s\": \"%s\"",
-								record->name, value ? value : "")));
-						return false;
-					}
-					else if (hookresult != newval)
-					{
-						free(newval);
-
-						/*
-						 * Having to cast away const here is annoying, but the
-						 * alternative is to declare assign_hooks as returning
-						 * char*, which would mean they'd have to cast away
-						 * const, or as both taking and returning char*, which
-						 * doesn't seem attractive either --- we don't want
-						 * them to scribble on the passed str.
-						 */
-						newval = (char *) hookresult;
-					}
-				}
-
-				if (retval)
-					retval->stringval = newval;
-				else
-					free(newval);
-				break;
-			}
-	}
-	return true;
-}
-
-/*
- * Check if the option can be set at this time. See guc.h for the precise
- * rules. 
- */
-static bool
-checkContext(int elevel, struct config_generic *record, GucContext context)
-{
-	switch (record->context)
-	{
-		case PGC_INTERNAL:
-			if (context != PGC_INTERNAL)
-			{
-				ereport(elevel,
-						(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
-						 errmsg("parameter \"%s\" cannot be changed",
-								record->name)));
-				return false;
-			}
-			break;
-		case PGC_POSTMASTER:
-			if (context == PGC_SIGHUP)
-				return false;
-
-			if (context != PGC_POSTMASTER)
-			{
-				ereport(elevel,
-						(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
-						 errmsg("parameter \"%s\" cannot be changed after server start",
-								record->name)));
-				return false;
-			}
-			break;
-		case PGC_SIGHUP:
-			if (context != PGC_SIGHUP && context != PGC_POSTMASTER)
-			{
-				ereport(elevel,
-						(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
-						 errmsg("parameter \"%s\" cannot be changed now",
-								record->name)));
-				return false;
-			}
-
-			/*
-			 * Hmm, the idea of the SIGHUP context is "ought to be global, but
-			 * can be changed after postmaster start". But there's nothing
-			 * that prevents a crafty administrator from sending SIGHUP
-			 * signals to individual backends only.
-			 */
-			break;
-		case PGC_BACKEND:
-			if (context == PGC_SIGHUP)
-			{
-				/*
-				 * If a PGC_BACKEND parameter is changed in the config file,
-				 * we want to accept the new value in the postmaster (whence
-				 * it will propagate to subsequently-started backends), but
-				 * ignore it in existing backends.	This is a tad klugy, but
-				 * necessary because we don't re-read the config file during
-				 * backend start.
-				 */
-				if (IsUnderPostmaster)
-				{
-					return false;
-				}
-			}
-			else if (context != PGC_BACKEND && context != PGC_POSTMASTER)
-			{
-				ereport(elevel,
-						(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
-						 errmsg("parameter \"%s\" cannot be set after connection start",
-								record->name)));
-				return false;
-			}
-			break;
-		case PGC_SUSET:
-			if (context == PGC_USERSET || context == PGC_BACKEND)
-			{
-				ereport(elevel,
-						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-						 errmsg("permission denied to set parameter \"%s\"",
-								record->name)));
-				return false;
-			}
-			break;
-		case PGC_USERSET:
-			/* always okay */
-			break;
-	}
-	return true;
-}
-
-/*
- * Get error level for different sources and context.
- */
-static int
-get_elevel(GucContext context, GucSource source)
-{
-	int elevel;
-	if (context == PGC_SIGHUP || source == PGC_S_DEFAULT)
-	{
-		/*
-		 * To avoid cluttering the log, only the postmaster bleats loudly
-		 * about problems with the config file.
-		 */
-		elevel = IsUnderPostmaster ? DEBUG2 : LOG;
-	}
-	else if (source == PGC_S_DATABASE || source == PGC_S_USER)
-		elevel = INFO;
-	else
-		elevel = ERROR;
-
-	return elevel;
-}
-
-/*
- * Verify if option exists and value is valid.
- * It is primary used for validation of items in configuration file.
- */
-bool
-verify_config_option(const char *name, const char *value,
-				GucContext context, GucSource source,
-				bool *isNewEqual, bool *isContextOK)
-{
-	int					   elevel;
-	struct config_generic *record;
-
-	elevel = get_elevel(context, source);
-
-	record = find_option(name, elevel);
-	if (record == NULL)
-	{
-		ereport(elevel,
-				(errcode(ERRCODE_UNDEFINED_OBJECT),
-			   errmsg("unrecognized configuration parameter \"%s\"", name)));
-		return false;
-	}
-
-	if (parse_value(elevel, record, value, &source, false, NULL))
-	{
-		/*
-		 * Mark record as present in the config file. Be carefull if
-		 * you use this function for another purpose than config file 
-		 * verification. It causes confusion in the config file parser.
-		 */
-		record->status |= GUC_IN_CONFFILE;
-
-		if (isNewEqual != NULL)
-			*isNewEqual = is_newvalue_equal(record, value);
-		if (isContextOK != NULL)
-			*isContextOK = checkContext(elevel, record, context);
-	}
-	else 
-		return false;
-
-    return true;
-}
-
 
 /*
  * Sets option `name' to given value. The value should be a string
@@ -4131,7 +3722,18 @@ set_config_option(const char *name, const char *value,
 	int			elevel;
 	bool		makeDefault;
 
-	elevel = get_elevel(context, source);
+	if (context == PGC_SIGHUP || source == PGC_S_DEFAULT)
+	{
+		/*
+		 * To avoid cluttering the log, only the postmaster bleats loudly
+		 * about problems with the config file.
+		 */
+		elevel = IsUnderPostmaster ? DEBUG2 : LOG;
+	}
+	else if (source == PGC_S_DATABASE || source == PGC_S_USER)
+		elevel = INFO;
+	else
+		elevel = ERROR;
 
 	record = find_option(name, elevel);
 	if (record == NULL)
@@ -4142,16 +3744,105 @@ set_config_option(const char *name, const char *value,
 		return false;
 	}
 
-	/* Check if change is allowed in the running context. */
-	if (!checkContext(elevel, record, context))
-		return false;
+	/*
+	 * Check if the option can be set at this time. See guc.h for the precise
+	 * rules. Note that we don't want to throw errors if we're in the SIGHUP
+	 * context. In that case we just ignore the attempt and return true.
+	 */
+	switch (record->context)
+	{
+		case PGC_INTERNAL:
+			if (context == PGC_SIGHUP)
+				return true;
+			if (context != PGC_INTERNAL)
+			{
+				ereport(elevel,
+						(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
+						 errmsg("parameter \"%s\" cannot be changed",
+								name)));
+				return false;
+			}
+			break;
+		case PGC_POSTMASTER:
+			if (context == PGC_SIGHUP)
+			{
+				if (changeVal && !is_newvalue_equal(record, value))
+					ereport(elevel,
+							(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
+							 errmsg("parameter \"%s\" cannot be changed after server start; configuration file change ignored",
+									name)));
+
+				return true;
+			}
+			if (context != PGC_POSTMASTER)
+			{
+				ereport(elevel,
+						(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
+						 errmsg("parameter \"%s\" cannot be changed after server start",
+								name)));
+				return false;
+			}
+			break;
+		case PGC_SIGHUP:
+			if (context != PGC_SIGHUP && context != PGC_POSTMASTER)
+			{
+				ereport(elevel,
+						(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
+						 errmsg("parameter \"%s\" cannot be changed now",
+								name)));
+				return false;
+			}
+
+			/*
+			 * Hmm, the idea of the SIGHUP context is "ought to be global, but
+			 * can be changed after postmaster start". But there's nothing
+			 * that prevents a crafty administrator from sending SIGHUP
+			 * signals to individual backends only.
+			 */
+			break;
+		case PGC_BACKEND:
+			if (context == PGC_SIGHUP)
+			{
+				/*
+				 * If a PGC_BACKEND parameter is changed in the config file,
+				 * we want to accept the new value in the postmaster (whence
+				 * it will propagate to subsequently-started backends), but
+				 * ignore it in existing backends.	This is a tad klugy, but
+				 * necessary because we don't re-read the config file during
+				 * backend start.
+				 */
+				if (IsUnderPostmaster)
+					return true;
+			}
+			else if (context != PGC_BACKEND && context != PGC_POSTMASTER)
+			{
+				ereport(elevel,
+						(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
+						 errmsg("parameter \"%s\" cannot be set after connection start",
+								name)));
+				return false;
+			}
+			break;
+		case PGC_SUSET:
+			if (context == PGC_USERSET || context == PGC_BACKEND)
+			{
+				ereport(elevel,
+						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+						 errmsg("permission denied to set parameter \"%s\"",
+								name)));
+				return false;
+			}
+			break;
+		case PGC_USERSET:
+			/* always okay */
+			break;
+	}
 
 	/*
 	 * Should we set reset/stacked values?	(If so, the behavior is not
 	 * transactional.)
 	 */
-	makeDefault = changeVal && (source <= PGC_S_OVERRIDE) &&
-					(value != NULL || source == PGC_S_FILE);
+	makeDefault = changeVal && (source <= PGC_S_OVERRIDE) && (value != NULL);
 
 	/*
 	 * Ignore attempted set if overridden by previously processed setting.
@@ -4180,23 +3871,44 @@ set_config_option(const char *name, const char *value,
 			{
 				struct config_bool *conf = (struct config_bool *) record;
 				bool		newval;
-				
-				if (!parse_value(elevel, record, value, &source, changeVal,
-					(union config_var_value*) &newval))
-					return false;
+
+				if (value)
+				{
+					if (!parse_bool(value, &newval))
+					{
+						ereport(elevel,
+								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+						  errmsg("parameter \"%s\" requires a Boolean value",
+								 name)));
+						return false;
+					}
+				}
+				else
+				{
+					newval = conf->reset_val;
+					source = conf->gen.reset_source;
+				}
+
+				if (conf->assign_hook)
+					if (!(*conf->assign_hook) (newval, changeVal, source))
+					{
+						ereport(elevel,
+								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+							 errmsg("invalid value for parameter \"%s\": %d",
+									name, (int) newval)));
+						return false;
+					}
 
 				if (changeVal || makeDefault)
 				{
 					/* Save old value to support transaction abort */
 					if (!makeDefault)
 						push_old_value(&conf->gen);
-
 					if (changeVal)
 					{
 						*conf->variable = newval;
 						conf->gen.source = source;
 					}
-
 					if (makeDefault)
 					{
 						GucStack   *stack;
@@ -4236,22 +3948,51 @@ set_config_option(const char *name, const char *value,
 				struct config_int *conf = (struct config_int *) record;
 				int			newval;
 
- 				if (!parse_value(elevel, record, value, &source, changeVal,
-					(union config_var_value*) &newval))
- 					return false;
+				if (value)
+				{
+					if (!parse_int(value, &newval, conf->gen.flags))
+					{
+						ereport(elevel,
+								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+						 errmsg("parameter \"%s\" requires an integer value",
+								name)));
+						return false;
+					}
+					if (newval < conf->min || newval > conf->max)
+					{
+						ereport(elevel,
+								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+								 errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
+										newval, name, conf->min, conf->max)));
+						return false;
+					}
+				}
+				else
+				{
+					newval = conf->reset_val;
+					source = conf->gen.reset_source;
+				}
+
+				if (conf->assign_hook)
+					if (!(*conf->assign_hook) (newval, changeVal, source))
+					{
+						ereport(elevel,
+								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+							 errmsg("invalid value for parameter \"%s\": %d",
+									name, newval)));
+						return false;
+					}
 
 				if (changeVal || makeDefault)
 				{
 					/* Save old value to support transaction abort */
 					if (!makeDefault)
 						push_old_value(&conf->gen);
-
 					if (changeVal)
 					{
 						*conf->variable = newval;
 						conf->gen.source = source;
 					}
-
 					if (makeDefault)
 					{
 						GucStack   *stack;
@@ -4291,22 +4032,51 @@ set_config_option(const char *name, const char *value,
 				struct config_real *conf = (struct config_real *) record;
 				double		newval;
 
-				if (!parse_value(elevel, record, value, &source, changeVal,
-					(union config_var_value*) &newval))
-					return false; 
+				if (value)
+				{
+					if (!parse_real(value, &newval))
+					{
+						ereport(elevel,
+								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+						  errmsg("parameter \"%s\" requires a numeric value",
+								 name)));
+						return false;
+					}
+					if (newval < conf->min || newval > conf->max)
+					{
+						ereport(elevel,
+								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+								 errmsg("%g is outside the valid range for parameter \"%s\" (%g .. %g)",
+										newval, name, conf->min, conf->max)));
+						return false;
+					}
+				}
+				else
+				{
+					newval = conf->reset_val;
+					source = conf->gen.reset_source;
+				}
+
+				if (conf->assign_hook)
+					if (!(*conf->assign_hook) (newval, changeVal, source))
+					{
+						ereport(elevel,
+								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+							 errmsg("invalid value for parameter \"%s\": %g",
+									name, newval)));
+						return false;
+					}
 
 				if (changeVal || makeDefault)
 				{
 					/* Save old value to support transaction abort */
 					if (!makeDefault)
 						push_old_value(&conf->gen);
-
 					if (changeVal)
 					{
 						*conf->variable = newval;
 						conf->gen.source = source;
 					}
-
 					if (makeDefault)
 					{
 						GucStack   *stack;
@@ -4346,22 +4116,82 @@ set_config_option(const char *name, const char *value,
 				struct config_string *conf = (struct config_string *) record;
 				char	   *newval;
 
-				if (!parse_value(elevel, record, value, &source, changeVal,
-					(union config_var_value*) &newval))
-					return false;
+				if (value)
+				{
+					newval = guc_strdup(elevel, value);
+					if (newval == NULL)
+						return false;
+					/*
+					 * The only sort of "parsing" check we need to do is
+					 * apply truncation if GUC_IS_NAME.
+					 */
+					if (conf->gen.flags & GUC_IS_NAME)
+						truncate_identifier(newval, strlen(newval), true);
+				}
+				else if (conf->reset_val)
+				{
+					/*
+					 * We could possibly avoid strdup here, but easier to make
+					 * this case work the same as the normal assignment case.
+					 */
+					newval = guc_strdup(elevel, conf->reset_val);
+					if (newval == NULL)
+						return false;
+					source = conf->gen.reset_source;
+				}
+				else
+				{
+					/* Nothing to reset to, as yet; so do nothing */
+					break;
+				}
+
+				if (conf->assign_hook)
+				{
+					const char *hookresult;
+
+					/*
+					 * If the hook ereports, we have to make sure we free
+					 * newval, else it will be a permanent memory leak.
+					 */
+					hookresult = call_string_assign_hook(conf->assign_hook,
+														 newval,
+														 changeVal,
+														 source);
+					if (hookresult == NULL)
+					{
+						free(newval);
+						ereport(elevel,
+								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+						 errmsg("invalid value for parameter \"%s\": \"%s\"",
+								name, value ? value : "")));
+						return false;
+					}
+					else if (hookresult != newval)
+					{
+						free(newval);
+
+						/*
+						 * Having to cast away const here is annoying, but the
+						 * alternative is to declare assign_hooks as returning
+						 * char*, which would mean they'd have to cast away
+						 * const, or as both taking and returning char*, which
+						 * doesn't seem attractive either --- we don't want
+						 * them to scribble on the passed str.
+						 */
+						newval = (char *) hookresult;
+					}
+				}
 
 				if (changeVal || makeDefault)
 				{
 					/* Save old value to support transaction abort */
 					if (!makeDefault)
 						push_old_value(&conf->gen);
-
 					if (changeVal)
 					{
 						set_string_field(conf, conf->variable, newval);
 						conf->gen.source = source;
 					}
-
 					if (makeDefault)
 					{
 						GucStack   *stack;
@@ -4937,7 +4767,8 @@ GetPGVariableResultDesc(const char *name)
 
 		/* need a tuple descriptor representing a single TEXT column */
 		tupdesc = CreateTemplateTupleDesc(1, false);
-		TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname, TEXTOID, -1, 0);
+		TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
+						   TEXTOID, -1, 0);
 	}
 	return tupdesc;
 }
@@ -5029,6 +4860,7 @@ ShowAllGUCConfig(DestReceiver *dest)
 		/* send it to dest */
 		do_tup_output(tstate, values);
 
+		/* clean up */
 		if (values[1] != NULL)
 			pfree(values[1]);
 	}
@@ -5482,9 +5314,6 @@ _ShowOption(struct config_generic * record, bool use_units)
 static bool
 is_newvalue_equal(struct config_generic *record, const char *newvalue)
 {
-	if (!newvalue)
-		return false;
-  
 	switch (record->vartype)
 	{
 		case PGC_BOOL:
@@ -5512,10 +5341,7 @@ is_newvalue_equal(struct config_generic *record, const char *newvalue)
 		{
 			struct config_string *conf = (struct config_string *) record;
 
-			if (!*conf->variable)	/* custom variable with no value yet */
-				return false;
-			else
-				return strcmp(*conf->variable, newvalue) == 0;
+			return strcmp(*conf->variable, newvalue) == 0;
 		}
 	}
 
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index e966ac9fd8..403d022b7a 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -7,7 +7,7 @@
  * Copyright (c) 2000-2006, PostgreSQL Global Development Group
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
- * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.74 2006/08/13 01:30:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.75 2006/08/14 02:27:27 momjian Exp $
  *--------------------------------------------------------------------
  */
 #ifndef GUC_H
@@ -193,9 +193,6 @@ extern void ParseLongOption(const char *string, char **name, char **value);
 extern bool set_config_option(const char *name, const char *value,
 				  GucContext context, GucSource source,
 				  bool isLocal, bool changeVal);
-extern bool verify_config_option(const char *name, const char *value,
-				GucContext context, GucSource source,
-				bool *isNewEqual, bool *isContextOK);
 extern char *GetConfigOptionByName(const char *name, const char **varname);
 extern void GetConfigOptionByNum(int varnum, const char **values, bool *noshow);
 extern int	GetNumConfigOptions(void);
diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h
index 6345fb1abd..a0ebf2c529 100644
--- a/src/include/utils/guc_tables.h
+++ b/src/include/utils/guc_tables.h
@@ -7,7 +7,7 @@
  *
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  *
- *	  $PostgreSQL: pgsql/src/include/utils/guc_tables.h,v 1.27 2006/08/13 02:22:24 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/include/utils/guc_tables.h,v 1.28 2006/08/14 02:27:27 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -143,8 +143,7 @@ struct config_generic
 #define GUC_HAVE_TENTATIVE	0x0001		/* tentative value is defined */
 #define GUC_HAVE_LOCAL		0x0002		/* a SET LOCAL has been executed */
 #define GUC_HAVE_STACK		0x0004		/* we have stacked prior value(s) */
-#define GUC_IN_CONFFILE		0x0008		/* value shows up in the configuration
-										   file (is not commented) */
+
 
 /* GUC records for specific variable types */
 
@@ -154,12 +153,11 @@ struct config_bool
 	/* these fields must be set correctly in initial value: */
 	/* (all but reset_val are constants) */
 	bool	   *variable;
-	bool		boot_val;
+	bool		reset_val;
 	GucBoolAssignHook assign_hook;
 	GucShowHook show_hook;
 	/* variable fields, initialized at runtime: */
 	bool		tentative_val;
-	bool		reset_val;
 };
 
 struct config_int
@@ -168,14 +166,13 @@ struct config_int
 	/* these fields must be set correctly in initial value: */
 	/* (all but reset_val are constants) */
 	int		   *variable;
-	int			boot_val;
+	int			reset_val;
 	int			min;
 	int			max;
 	GucIntAssignHook assign_hook;
 	GucShowHook show_hook;
 	/* variable fields, initialized at runtime: */
 	int			tentative_val;
-	int			reset_val;
 };
 
 struct config_real
@@ -184,14 +181,13 @@ struct config_real
 	/* these fields must be set correctly in initial value: */
 	/* (all but reset_val are constants) */
 	double	   *variable;
-	double		boot_val;
+	double		reset_val;
 	double		min;
 	double		max;
 	GucRealAssignHook assign_hook;
 	GucShowHook show_hook;
 	/* variable fields, initialized at runtime: */
 	double		tentative_val;
-	double		reset_val;
 };
 
 struct config_string