*** a/src/backend/utils/misc/guc-file.l
--- b/src/backend/utils/misc/guc-file.l
***************
*** 110,116 **** ProcessConfigFile(GucContext context)
  				   *tail;
  	char	   *cvc = NULL;
  	struct config_string *cvc_struct;
! 	int			i;
  
  	Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
  
--- 110,117 ----
  				   *tail;
  	char	   *cvc = NULL;
  	struct config_string *cvc_struct;
! 	int 		i;
! 	bool		OK = true;
  
  	Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
  
***************
*** 123,135 **** ProcessConfigFile(GucContext context)
  		elevel = IsUnderPostmaster ? DEBUG2 : LOG;
  	}
  	else
! 		elevel = ERROR;
  
  	/* Parse the file into a list of option names and values */
  	head = tail = NULL;
  
  	if (!ParseConfigFile(ConfigFileName, NULL, 0, elevel, &head, &tail))
! 		goto cleanup_list;
  
  	/*
  	 * We need the proposed new value of custom_variable_classes to check
--- 124,136 ----
  		elevel = IsUnderPostmaster ? DEBUG2 : LOG;
  	}
  	else
! 		elevel = LOG;
  
  	/* Parse the file into a list of option names and values */
  	head = tail = NULL;
  
  	if (!ParseConfigFile(ConfigFileName, NULL, 0, elevel, &head, &tail))
! 		OK = false;
  
  	/*
  	 * We need the proposed new value of custom_variable_classes to check
***************
*** 161,167 **** ProcessConfigFile(GucContext context)
  			goto cleanup_list;
  		if (!call_string_check_hook(cvc_struct, &cvc, &extra,
  									PGC_S_FILE, elevel))
! 			goto cleanup_list;
  		if (extra)
  			free(extra);
  	}
--- 162,168 ----
  			goto cleanup_list;
  		if (!call_string_check_hook(cvc_struct, &cvc, &extra,
  									PGC_S_FILE, elevel))
! 			OK = false;
  		if (extra)
  			free(extra);
  	}
***************
*** 201,207 **** ProcessConfigFile(GucContext context)
  						(errcode(ERRCODE_UNDEFINED_OBJECT),
  						 errmsg("unrecognized configuration parameter \"%s\"",
  								item->name)));
! 				goto cleanup_list;
  			}
  			/*
  			 * 2. There is no GUC entry.  If we called set_config_option then
--- 202,208 ----
  						(errcode(ERRCODE_UNDEFINED_OBJECT),
  						 errmsg("unrecognized configuration parameter \"%s\"",
  								item->name)));
! 				OK = false;
  			}
  			/*
  			 * 2. There is no GUC entry.  If we called set_config_option then
***************
*** 221,228 **** ProcessConfigFile(GucContext context)
  
  		if (!set_config_option(item->name, item->value, context,
  							   PGC_S_FILE, GUC_ACTION_SET, false))
! 			goto cleanup_list;
  	}
  
  	/*
  	 * Check for variables having been removed from the config file, and
--- 222,235 ----
  
  		if (!set_config_option(item->name, item->value, context,
  							   PGC_S_FILE, GUC_ACTION_SET, false))
! 			OK = false;
! 		/* stop at the first error if we are postmaster's child */
! 		if (IsUnderPostmaster && !OK)
! 			break;
  	}
+ 	/* Don't change configuration options if errors were detected earlier */
+ 	if (!OK)
+ 		goto cleanup_list;	
  
  	/*
  	 * Check for variables having been removed from the config file, and
***************
*** 345,350 **** ProcessConfigFile(GucContext context)
--- 352,361 ----
  	FreeConfigVariables(head);
  	if (cvc)
  		free(cvc);
+ 	/* If we got an error during postmaster's start - complain and bail out */
+ 	if (!OK && context == PGC_POSTMASTER)
+ 		ereport(ERROR,
+ 				(errmsg("errors detected while parsing configuration files")));
  }
  
  /*
***************
*** 437,442 **** ParseConfigFile(const char *config_file, const char *calling_file,
--- 448,459 ----
   * already been ereport'd, it is only necessary for the caller to clean up
   * its own state and release the name/value pairs list.
   *
+  * If elevel < ERROR then we don't return immediately on the first error,
+  * although we do return after comming across 100 of them. This is to prevent
+  * trashing out logs when parsing a completely bogus file. We consider all 
+  * parse errors in "includes" as a single one for simplicity, it's unlikely we 
+  * ever come across the bogus file with valid include directives.
+  *
   * Note: if elevel >= ERROR then an error will not return control to the
   * caller, and internal state such as open files will not be cleaned up.
   * This case occurs only during postmaster or standalone-backend startup,
***************
*** 447,455 **** bool
  ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
  			  ConfigVariable **head_p, ConfigVariable **tail_p)
  {
- 	bool		OK = true;
  	YY_BUFFER_STATE lex_buffer;
! 	int			token;
  
  	/*
  	 * Parse
--- 464,472 ----
  ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
  			  ConfigVariable **head_p, ConfigVariable **tail_p)
  {
  	YY_BUFFER_STATE lex_buffer;
! 	int			token,
! 				errorcount;
  
  	/*
  	 * Parse
***************
*** 458,463 **** ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
--- 475,481 ----
  	yy_switch_to_buffer(lex_buffer);
  
  	ConfigFileLineno = 1;
+ 	errorcount = 0;
  
  	/* This loop iterates once per logical line */
  	while ((token = yylex()))
***************
*** 512,523 **** ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
  			if (!ParseConfigFile(opt_value, config_file,
  								 depth + 1, elevel,
  								 head_p, tail_p))
! 			{
! 				pfree(opt_name);
! 				pfree(opt_value);
! 				OK = false;
! 				goto cleanup_exit;
! 			}
  			yy_switch_to_buffer(lex_buffer);
  			ConfigFileLineno = save_ConfigFileLineno;
  			pfree(opt_name);
--- 530,536 ----
  			if (!ParseConfigFile(opt_value, config_file,
  								 depth + 1, elevel,
  								 head_p, tail_p))
! 				errorcount++;
  			yy_switch_to_buffer(lex_buffer);
  			ConfigFileLineno = save_ConfigFileLineno;
  			pfree(opt_name);
***************
*** 576,602 **** ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
  		/* break out of loop if read EOF, else loop for next line */
  		if (token == 0)
  			break;
  	}
  
  	/* successful completion of parsing */
- 	goto cleanup_exit;
- 
-  parse_error:
- 	if (token == GUC_EOL || token == 0)
- 		ereport(elevel,
- 				(errcode(ERRCODE_SYNTAX_ERROR),
- 				 errmsg("syntax error in file \"%s\" line %u, near end of line",
- 						config_file, ConfigFileLineno - 1)));
- 	else
- 		ereport(elevel,
- 				(errcode(ERRCODE_SYNTAX_ERROR),
- 				 errmsg("syntax error in file \"%s\" line %u, near token \"%s\"",
- 						config_file, ConfigFileLineno, yytext)));
- 	OK = false;
- 
- cleanup_exit:
  	yy_delete_buffer(lex_buffer);
! 	return OK;
  }
  
  
--- 589,625 ----
  		/* break out of loop if read EOF, else loop for next line */
  		if (token == 0)
  			break;
+ 		/* skip over parse_error if we made it this far without errors */
+ 		continue;
+ 	
+  	parse_error:
+ 		if (token == GUC_EOL || token == 0)
+ 			ereport(elevel,
+ 					(errcode(ERRCODE_SYNTAX_ERROR),
+ 					 errmsg("syntax error in file \"%s\" line %u, near end of line",
+ 							config_file, ConfigFileLineno - 1)));
+ 		else
+ 			ereport(elevel,
+ 					(errcode(ERRCODE_SYNTAX_ERROR),
+ 					 errmsg("syntax error in file \"%s\" line %u, near token \"%s\"",
+ 							config_file, ConfigFileLineno, yytext)));
+ 		errorcount++;
+ 		/* fast forward till the next EOL/EOF */
+ 		while (token && token != GUC_EOL)
+ 			token = yylex();
+ 		
+ 		/* break out of loop on EOF */
+ 		if (token == 0)
+ 			break;
+ 		
+ 		/* avoid producing too much noise when parsing a bogus file */
+ 		if (IsUnderPostmaster || errorcount >= 100)
+ 			break;
  	}
  
  	/* successful completion of parsing */
  	yy_delete_buffer(lex_buffer);
! 	return (errorcount == 0);
  }
  
  
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
***************
*** 5074,5080 **** set_config_option(const char *name, const char *value,
  	bool		prohibitValueChange = false;
  	bool		makeDefault;
  
! 	if (context == PGC_SIGHUP || source == PGC_S_DEFAULT)
  	{
  		/*
  		 * To avoid cluttering the log, only the postmaster bleats loudly
--- 5074,5080 ----
  	bool		prohibitValueChange = false;
  	bool		makeDefault;
  
! 	if (source == PGC_S_FILE || source == PGC_S_DEFAULT)
  	{
  		/*
  		 * To avoid cluttering the log, only the postmaster bleats loudly
