diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l
index a094c7a..25e1a07 100644
*** a/src/backend/utils/misc/guc-file.l
--- b/src/backend/utils/misc/guc-file.l
*************** ParseConfigFp(FILE *fp, const char *conf
*** 512,518 ****
  		}
  
  		/* OK, process the option name and value */
! 		if (guc_name_compare(opt_name, "include") == 0)
  		{
  			/*
  			 * An include directive isn't a variable and should be processed
--- 512,535 ----
  		}
  
  		/* OK, process the option name and value */
! 		if (guc_name_compare(opt_name, "includedir") == 0)
! 		{
! 			/*
! 			 * An includedir directive isn't a variable and should be processed
! 			 * immediately.
! 			 */
! 			unsigned int save_ConfigFileLineno = ConfigFileLineno;
! 
! 			if (!ParseConfigDirectory(opt_value, config_file,
! 								 depth + 1, elevel,
! 								 head_p, tail_p))
! 				OK = false;
! 			yy_switch_to_buffer(lex_buffer);
! 			ConfigFileLineno = save_ConfigFileLineno;
! 			pfree(opt_name);
! 			pfree(opt_value);
! 		}
! 		else if (guc_name_compare(opt_name, "include") == 0)
  		{
  			/*
  			 * An include directive isn't a variable and should be processed
*************** ParseConfigFp(FILE *fp, const char *conf
*** 599,604 ****
--- 616,727 ----
  	return OK;
  }
  
+ static int
+ comparestr(const void *a, const void *b)
+ {
+ 	return strcmp(*(char **) a, *(char **) b);
+ }
+ 
+ /*
+  * Read and parse all config files in a subdirectory in alphabetical order
+  */
+ bool
+ ParseConfigDirectory(const char *includedir,
+ 				const char *calling_file,
+ 				int depth, int elevel,
+ 				ConfigVariable **head_p,
+ 				ConfigVariable **tail_p)
+ {
+ 	DIR *d;
+ 	struct dirent *de;
+ 	char directory[MAXPGPATH];
+ 	char **filenames = NULL;
+ 	int num_filenames = 0;
+ 	int size_filenames = 0;
+ 	bool status;
+ 
+ 	if (is_absolute_path(includedir))
+ 		sprintf(directory, "%s", includedir);
+ 	else
+ 		sprintf(directory, "%s/%s", configdir, includedir);
+ 	d = AllocateDir(directory);
+ 	if (d == NULL)
+ 	{
+ 		/*
+ 		 * Not finding the configuration directory is not fatal, because we
+ 		 * still have the main postgresql.conf file. Return true so the
+ 		 * complete config parsing doesn't fail in this case. Also avoid
+ 		 * logging this, since it can be a normal situtation.
+ 		 */
+ 		return true;
+ 	}
+ 
+ 	/*
+ 	 * Read the directory and put the filenames in an array, so we can sort
+ 	 * them prior to processing the contents.
+ 	 */
+ 	while ((de = ReadDir(d, directory)) != NULL)
+ 	{
+ 		struct stat st;
+ 		char filename[MAXPGPATH];
+ 
+ 		/*
+ 		 * Only parse files with names ending in ".conf".
+ 		 * This automatically excludes things like "." and "..", as well
+ 		 * as backup files and editor debris.
+ 		 */
+ 		if (strlen(de->d_name) < 6)
+ 			continue;
+ 		if (strcmp(de->d_name + strlen(de->d_name) - 5, ".conf") != 0)
+ 			continue;
+ 
+ 		snprintf(filename, MAXPGPATH, "%s/%s", directory, de->d_name);
+ 		if (stat(filename, &st) == 0)
+ 		{
+ 			if (!S_ISDIR(st.st_mode))
+ 			{
+ 				/* Add file to list */
+ 				if (num_filenames == size_filenames)
+ 				{
+ 					/* Increase size of array in blocks of 32 */
+ 					size_filenames += 32;
+ 					filenames = guc_realloc(elevel, filenames, size_filenames * sizeof(char *));
+ 				}
+ 				filenames[num_filenames] = strdup(filename);
+ 				num_filenames++;
+ 			}
+ 		}
+ 	}
+ 	if (num_filenames > 0)
+ 	{
+ 		int i;
+ 		qsort(filenames, num_filenames, sizeof(char *), comparestr);
+ 		for (i = 0; i < num_filenames; i++)
+ 		{
+ 			if (!ParseConfigFile(filenames[i], NULL,
+ 								 0, elevel,head_p, tail_p))
+ 			{
+ 				status = false;
+ 				goto cleanup;
+ 			}
+ 		}
+ 	}
+ 	status = true;
+ 
+ cleanup:
+ 	if (num_filenames > 0)
+ 	{
+ 		int i;
+ 
+ 		for (i = 0; i < num_filenames; i++)
+ 		{
+ 			free(filenames[i]);
+ 		}
+ 		free(filenames);
+ 	}
+ 	FreeDir(d);
+ 	return status;
+ }
  
  /*
   * Free a list of ConfigVariables, including the names and the values
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index da7b6d4..fc9b376 100644
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
*************** static int	effective_io_concurrency;
*** 481,486 ****
--- 481,488 ----
  /* should be static, but commands/variable.c needs to get at this */
  char	   *role_string;
  
+ /* Needed for ProcessConfigFile calls, such as a config reload at SIGHUP */
+ char	   *configdir;
  
  /*
   * Displayable names for context types (enum GucContext)
*************** static bool validate_option_array_item(c
*** 3297,3303 ****
  /*
   * Some infrastructure for checking malloc/strdup/realloc calls
   */
! static void *
  guc_malloc(int elevel, size_t size)
  {
  	void	   *data;
--- 3299,3305 ----
  /*
   * Some infrastructure for checking malloc/strdup/realloc calls
   */
! void *
  guc_malloc(int elevel, size_t size)
  {
  	void	   *data;
*************** guc_malloc(int elevel, size_t size)
*** 3310,3316 ****
  	return data;
  }
  
! static void *
  guc_realloc(int elevel, void *old, size_t size)
  {
  	void	   *data;
--- 3312,3318 ----
  	return data;
  }
  
! void *
  guc_realloc(int elevel, void *old, size_t size)
  {
  	void	   *data;
*************** InitializeOneGUCOption(struct config_gen
*** 4007,4013 ****
  bool
  SelectConfigFiles(const char *userDoption, const char *progname)
  {
- 	char	   *configdir;
  	char	   *fname;
  	struct stat stat_buf;
  
--- 4009,4014 ----
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 8e3057a..af47e95 100644
*** a/src/include/utils/guc.h
--- b/src/include/utils/guc.h
*************** extern bool ParseConfigFp(FILE *fp, cons
*** 117,122 ****
--- 117,123 ----
  			  int depth, int elevel,
  			  ConfigVariable **head_p, ConfigVariable **tail_p);
  extern void FreeConfigVariables(ConfigVariable *list);
+ extern char *configdir;
  
  /*
   * The possible values of an enum variable are specified by an array of
*************** extern const char *GetConfigOption(const
*** 302,307 ****
--- 303,313 ----
  				bool restrict_superuser);
  extern const char *GetConfigOptionResetString(const char *name);
  extern void ProcessConfigFile(GucContext context);
+ extern bool ParseConfigDirectory(const char *includedir,
+ 						 const char *calling_file,
+ 						 int depth, int elevel,
+ 						 ConfigVariable **head_p,
+ 						 ConfigVariable **tail_p);
  extern void InitializeGUCOptions(void);
  extern bool SelectConfigFiles(const char *userDoption, const char *progname);
  extern void ResetAllOptions(void);
*************** extern void GUC_check_errcode(int sqlerr
*** 360,365 ****
--- 366,377 ----
  
  
  /*
+  * Functions used for memory allocation in guc.
+  */
+ void *guc_malloc(int elevel, size_t size);
+ void *guc_realloc(int elevel, void *old, size_t size);
+ 
+ /*
   * The following functions are not in guc.c, but are declared here to avoid
   * having to include guc.h in some widely used headers that it really doesn't
   * belong in.
