*** a/src/backend/access/transam/xact.c
--- b/src/backend/access/transam/xact.c
***************
*** 1844,1849 **** CommitTransaction(void)
--- 1844,1851 ----
  	/* close large objects before lower-level cleanup */
  	AtEOXact_LargeObject(true);
  
+ 	AtEOXact_UpdateAutoConfFiles(true);
+ 
  	/*
  	 * Mark serializable transaction as complete for predicate locking
  	 * purposes.  This should be done as late as we can put it and still allow
***************
*** 2302,2307 **** AbortTransaction(void)
--- 2304,2310 ----
  	AtAbort_Portals();
  	AtEOXact_LargeObject(false);
  	AtAbort_Notify();
+ 	AtEOXact_UpdateAutoConfFiles(false);
  	AtEOXact_RelationMap(false);
  
  	/*
*** a/src/backend/commands/dbcommands.c
--- b/src/backend/commands/dbcommands.c
***************
*** 58,65 ****
--- 58,74 ----
  #include "utils/snapmgr.h"
  #include "utils/syscache.h"
  #include "utils/tqual.h"
+ #include "utils/guc_tables.h"
+ #include "utils/memutils.h"
  
  
+ /* lock file used in edit postgresql.auto.conf */
+ struct lock_file
+ {
+ 	int			fd;
+ 	char		filename[MAXPGPATH];
+ };
+ 
  typedef struct
  {
  	Oid			src_dboid;		/* source (template) DB */
***************
*** 72,77 **** typedef struct
--- 81,88 ----
  	Oid			dest_tsoid;		/* tablespace we are trying to move to */
  } movedb_failure_params;
  
+ static struct lock_file *lockConfFile = NULL;
+ 
  /* non-export function prototypes */
  static void createdb_failure_callback(int code, Datum arg);
  static void movedb(const char *dbname, const char *tblspcname);
***************
*** 86,91 **** static void remove_dbtablespaces(Oid db_id);
--- 97,108 ----
  static bool check_db_file_conflict(Oid db_id);
  static int	errdetail_busy_db(int notherbackends, int npreparedxacts);
  
+ static int	commit_lock_file(struct lock_file * lk);
+ static void	rollback_lock_file(struct lock_file * lk);
+ static int	close_lock_file(struct lock_file * lk);
+ static void writeAutoConffile(int fd, ConfigVariable **head_p, char *config_file);
+ static void replace_autoline(ConfigVariable **head_p, ConfigVariable **tail_p,
+ 			char *config_file, char *name, char *value, bool value_is_string);
  
  /*
   * CREATE DATABASE
***************
*** 1434,1439 **** AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
--- 1451,1778 ----
  
  
  /*
+  * create a postgres.auto.conf.lock file for postgres.auto.conf 
+  * file so that it act as an lock to prevent concurrent edit on
+  * postgres.auto.conf file
+  */
+ static int
+ lock_confile(struct lock_file * lk, const char *path, int flags)
+ {
+ 	int			ntries = 0;
+ 
+ 	strcpy(lk->filename, path);
+ 	strcat(lk->filename, CONF_LOCK_POSTFIX);
+ 
+ tryAgain:
+ 	lk->fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0600);
+ 	if (0 > lk->fd)
+ 	{
+ 		/*
+ 		 * Couldn't create the lock file. Probably it already exists. If so
+ 		 * wait for some time
+ 		 */
+ 		ntries++;
+ 		if ((errno != EEXIST && errno != EACCES) || ntries > 100)
+ 		{
+ 			if (errno != EEXIST)
+ 			{
+ 				ereport(LOG,
+ 						(errcode_for_file_access(),
+ 						 errmsg("could not create lock file \"%s\": %m",
+ 								lk->filename)));
+ 			}
+ 			else
+ 			{
+ 				ereport(LOG,
+ 						(errcode_for_file_access(),
+ 						 errmsg("could not create lock file \"%s\": %m ", lk->filename),
+ 						 errhint("May be too many concurrent edit into file happening, please wait!! and retry"
+ 								 "or .lock is file accidently left there please clean the file from config_dir")));
+ 			}
+ 
+ 			lk->filename[0] = 0;
+ 		}
+ 		else
+ 		{
+ 			pg_usleep(100000);	/* in total wait for 10sec */
+ 			goto tryAgain;
+ 		}
+ 	}
+ 
+ 	return lk->fd;
+ }
+ 
+ /* function to close the postgres.auto.conf.lock file */
+ int
+ close_lock_file(struct lock_file * lk)
+ {
+ 	int			fd = lk->fd;
+ 
+ 	lk->fd = -1;
+ 	return close(fd);
+ }
+ 
+ 
+ /*
+  * On commit, rename postgres.auto.conf.lock to postgres.auto.conf
+  * As postgres.auto.conf.lock contains updated parameter values.
+  */
+ int
+ commit_lock_file(struct lock_file * lk)
+ {
+ 	char		result_file[MAXPGPATH];
+ 	size_t		i;
+ 
+ 	if (lk->fd >= 0 && close_lock_file(lk))
+ 		return -1;
+ 	strcpy(result_file, lk->filename);
+ 	i = strlen(result_file) - 5;	/* remove .lock charecters */
+ 	result_file[i] = 0;
+ 	if (rename(lk->filename, result_file))
+ 		return -1;
+ 	lk->filename[0] = 0;
+ 	return 0;
+ }
+ 
+ 
+ /*
+  * On rollback, Delete the postgres.auto.conf.lock file, As we did not
+  * modifed anything in postgres.auto.conf
+  */
+ void
+ rollback_lock_file(struct lock_file * lk)
+ {
+ 	if (lk->filename[0])
+ 	{
+ 		if (lk->fd >= 0)
+ 		{
+ 			/* cloase the file */
+ 			close(lk->fd);
+ 		}
+ 
+ 		/* now remove the file */
+ 		unlink(lk->filename);
+ 	}
+ 
+ 	lk->filename[0] = 0;
+ }
+ 
+ 
+ /* Write updated configuration parameter values into postgres.auto.conf.lock */
+ static void
+ writeAutoConffile(int fd, ConfigVariable **head_p, char *config_file)
+ {
+ 	ConfigVariable *item;
+ 	StringInfoData buf;
+ 
+ 	initStringInfo(&buf);
+ 
+ 	for (item = *head_p; item != NULL; item = item->next)
+ 	{
+ 		appendStringInfoString(&buf, item->name);
+ 		appendStringInfoString(&buf, " = ");
+ 
+ 		if (true == item->value_is_string)
+ 		{
+ 			appendStringInfoString(&buf, "\'");
+ 			appendStringInfoString(&buf, item->value);
+ 			appendStringInfoString(&buf, "\'");
+ 		}
+ 		else
+ 		{
+ 			appendStringInfoString(&buf, item->value);
+ 		}
+ 
+ 		appendStringInfoString(&buf, "\n");
+ 
+ 		if (write(fd, buf.data, buf.len) < 0)
+ 		{
+ 			ereport(ERROR,
+ 					(errmsg("failed to write into to \"postgresql.auto.conf.lock\" file")));
+ 		}
+ 
+ 		resetStringInfo(&buf);
+ 	}
+ 
+ 	pfree(buf.data);
+ 	return;
+ }
+ 
+ 
+ /*
+  * Replace the updated configuration parameter value in postgres.auto.conf
+  * file lines. If it is new then append extra line at the end of lines.
+  */
+ static void
+ replace_autoline(ConfigVariable **head_p, ConfigVariable **tail_p,
+ 					char *config_file, char *name, char *value,
+ 					bool value_is_string)
+ {
+ 
+ 	ConfigVariable *item;
+ 
+ 	if (NULL != *head_p)
+ 	{
+ 		for (item = *head_p; item != NULL; item = item->next)
+ 		{
+ 			if (strcmp(item->name, name) == 0)
+ 			{
+ 				pfree(item->value);
+ 				item->value = pstrdup(value);
+ 				return;
+ 			}
+ 		}
+ 	}
+ 
+ 	item = palloc(sizeof *item);
+ 	item->name = pstrdup(name);
+ 	item->value = pstrdup(value);
+ 	item->value_is_string = value_is_string;
+ 	item->filename = pstrdup(config_file);
+ 	item->next = NULL;
+ 
+ 	if (*head_p == NULL)
+ 	{
+ 		item->sourceline = 1;
+ 		*head_p = item;
+ 	}
+ 	else
+ 	{
+ 		item->sourceline = (*tail_p)->sourceline+1;
+ 		(*tail_p)->next = item;
+ 	}
+ 
+ 	*tail_p = item;
+ 
+ 	return;
+ }
+ 
+ 
+ /*
+  * Edit postgres.conf parameters WITH SQL commands "SET PERSISTENT"
+  * by adding new postgres.auto.conf file in include configuration directory
+  * which will be processed at the end of postgres.conf file
+  */
+ void
+ set_config_file(VariableSetStmt *setstmt)
+ {
+ 	char	   *name;
+ 	char	   *value;
+ 	int			fd = -1;
+ 	FILE	   *infile;
+ 	struct config_generic *record;
+ 	char		abs_path[MAXPGPATH];
+ 	ConfigVariable *head_p = NULL;
+ 	ConfigVariable *tail_p = NULL;
+ 
+ 	/*
+ 	 * This command is modifing the configuration file so no need of
+ 	 * transaction properties, so not allowed inside a transaction.
+ 	 */
+ 	if (IsTransactionBlock())
+ 	{
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
+ 				 errmsg("SET PERSISTENT command is not allowed inside a transaction")));
+ 	}
+ 
+ 	if (!superuser())
+ 	{
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ 				 (errmsg("must be superuser to execute SET PERSISTENT command"))));
+ 	}
+ 
+ 	/*
+ 	 * Validate the name and arguments [value1, value2 ... ].
+ 	 */
+ 
+ 	name = pstrdup(setstmt->name);
+ 	value = ExtractSetVariableArgs(setstmt);
+ 
+ 	record = validate_conf_option(name, value);
+ 	if (!record)
+ 		ereport(ERROR,
+ 				(errmsg("invalid value for parameter \"%s\": \"%s\"", name, value)));
+ 
+ 	/* Create the postgres.auto.conf.lock file */
+ 	join_path_components(abs_path, data_directory, AutoConfigFileName);
+ 	canonicalize_path(abs_path);
+ 
+ 	lockConfFile = MemoryContextAllocZero(TopTransactionContext, sizeof(struct lock_file));
+ 
+ 	fd = lock_confile(lockConfFile, abs_path, 0);
+ 	if (fd < 0)
+ 	{
+ 		pfree(lockConfFile);
+ 		lockConfFile = NULL;
+ 		ereport(ERROR,
+ 				(errmsg("\"postgresql.auto.conf.lock\" file creation failed")));
+ 	}
+ 
+ 	/* open postgres.auto.conf file */
+ 	infile = AllocateFile(abs_path, "r");
+ 	if (infile == NULL)
+ 	{
+ 		ereport(ERROR,
+ 				(errmsg("failed to open \"postgresql.auto.conf\" file")));
+ 	}
+ 
+ 	/* Parse the postgres.auto.conf file */
+ 	ParseConfigFp(infile, abs_path, -1, LOG, &head_p, &tail_p);
+ 
+ 	FreeFile(infile);
+ 
+ 	/* replace with new value */
+ 	replace_autoline(&head_p, &tail_p, abs_path, name, value,
+ 					  (record->vartype == PGC_STRING) ? true : false);
+ 
+ 	/* Write the New contents to postgres.auto.conf.lock file */
+ 	writeAutoConffile(fd, &head_p, abs_path);
+ 
+ 	/*
+ 	 * On Commit, rename postgres.auto.conf.lock to postgres.auto.conf
+ 	 * and On Rollback, delete the postgres.auto.conf.lock
+ 	 */
+ 
+ 	return;
+ }
+ 
+ /*
+  * This routine is called during transaction commit or abort.
+  *
+  * On commit, renames the .auto.conf.lock to .auto.conf, for updateding changes
+  * into .auto.conf file
+  *
+  * On abort, just delete the .auto.conf.lock file.
+  *
+  * NB: this should be the last step before actual transaction commit.
+  * If any error aborts the transaction after we run this code, the postmaster
+  * will still have received and cached the changed data; so minimize the
+  * window for such problems.
+  */
+ void
+ AtEOXact_UpdateAutoConfFiles(bool isCommit)
+ {
+ 	if (lockConfFile)
+ 	{
+ 		if (isCommit)
+ 		{
+ 			if (commit_lock_file(lockConfFile) < 0)
+ 				ereport(ERROR,
+ 				(errmsg("commiting chages to \"postgresql.auto.conf\" failed")));
+ 		}
+ 		else
+ 		{
+ 			rollback_lock_file(lockConfFile);
+ 		}
+ 
+ 		pfree(lockConfFile);
+ 		lockConfFile = NULL;
+ 	}
+ }
+ 
+ /*
   * ALTER DATABASE name OWNER TO newowner
   */
  void
*** a/src/backend/parser/gram.y
--- b/src/backend/parser/gram.y
***************
*** 564,571 **** static void processCASbits(int cas_bits, int location, const char *constrType,
  	OBJECT_P OF OFF OFFSET OIDS ON ONLY OPERATOR OPTION OPTIONS OR
  	ORDER OUT_P OUTER_P OVER OVERLAPS OVERLAY OWNED OWNER
  
! 	PARSER PARTIAL PARTITION PASSING PASSWORD PLACING PLANS POSITION
! 	PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY
  	PRIOR PRIVILEGES PROCEDURAL PROCEDURE
  
  	QUOTE
--- 564,571 ----
  	OBJECT_P OF OFF OFFSET OIDS ON ONLY OPERATOR OPTION OPTIONS OR
  	ORDER OUT_P OUTER_P OVER OVERLAPS OVERLAY OWNED OWNER
  
! 	PARSER PARTIAL PARTITION PASSING PASSWORD PERSISTENT PLACING PLANS
! 	POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY
  	PRIOR PRIVILEGES PROCEDURAL PROCEDURE
  
  	QUOTE
***************
*** 1293,1298 **** VariableSetStmt:
--- 1293,1307 ----
  					n->is_local = false;
  					$$ = (Node *) n;
  				}
+ 			| SET PERSISTENT var_name '=' var_list
+ 				{
+ 					VariableSetStmt *n = makeNode(VariableSetStmt);
+ 					n->kind = VAR_SET_VALUE;
+ 					n->name = $3;
+ 					n->args = $5;
+ 					n->is_persistent = true;
+ 					$$ = (Node *)n;
+ 				}
  		;
  
  set_rest:
***************
*** 12586,12591 **** unreserved_keyword:
--- 12595,12601 ----
  			| PARTITION
  			| PASSING
  			| PASSWORD
+ 			| PERSISTENT
  			| PLANS
  			| PRECEDING
  			| PREPARE
*** a/src/backend/postmaster/postmaster.c
--- b/src/backend/postmaster/postmaster.c
***************
*** 507,512 **** PostmasterMain(int argc, char *argv[])
--- 507,513 ----
  	char	   *userDoption = NULL;
  	bool		listen_addr_saved = false;
  	int			i;
+ 	char		conf_lock_file[MAXPGPATH];
  
  	MyProcPid = PostmasterPid = getpid();
  
***************
*** 1163,1168 **** PostmasterMain(int argc, char *argv[])
--- 1164,1174 ----
  	 */
  	RemovePgTempFiles();
  
+ 	/* Remove postgres.auto.conf.lock file make be left over from last crash */
+ 	strcpy(conf_lock_file, AutoConfigFileName);
+ 	strcat(conf_lock_file, CONF_LOCK_POSTFIX);
+ 	unlink(conf_lock_file);
+ 
  	/*
  	 * Remember postmaster startup time
  	 */
*** a/src/backend/replication/basebackup.c
--- b/src/backend/replication/basebackup.c
***************
*** 581,586 **** sendDir(char *path, int basepathlen, bool sizeonly)
--- 581,592 ----
  					strlen(PG_TEMP_FILE_PREFIX)) == 0)
  			continue;
  
+ 		/* skip lock files used in postgresql.auto.conf edit */
+ 		if (strncmp(de->d_name,
+ 					"postgresql.auto.conf.lock",
+ 					strlen("postgresql.auto.conf.lock")) == 0)
+ 			continue;
+ 
  		/*
  		 * If there's a backup_label file, it belongs to a backup started by
  		 * the user with pg_start_backup(). It is *not* correct for this
*** a/src/backend/tcop/utility.c
--- b/src/backend/tcop/utility.c
***************
*** 1145,1151 **** standard_ProcessUtility(Node *parsetree,
  			break;
  
  		case T_VariableSetStmt:
! 			ExecSetVariableStmt((VariableSetStmt *) parsetree);
  			break;
  
  		case T_VariableShowStmt:
--- 1145,1158 ----
  			break;
  
  		case T_VariableSetStmt:
! 			if (((VariableSetStmt *) parsetree)->is_persistent == true)
! 			{
! 				set_config_file((VariableSetStmt *) parsetree);
! 			}
! 			else
! 			{
! 				ExecSetVariableStmt((VariableSetStmt *) parsetree);
! 			}
  			break;
  
  		case T_VariableShowStmt:
*** a/src/backend/utils/misc/guc-file.l
--- b/src/backend/utils/misc/guc-file.l
***************
*** 533,538 **** ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
--- 533,539 ----
  	{
  		char	   *opt_name = NULL;
  		char	   *opt_value = NULL;
+ 		bool		is_string = false;
  		ConfigVariable *item;
  
  		if (token == GUC_EOL)	/* empty or comment line */
***************
*** 556,562 **** ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
--- 557,566 ----
  			token != GUC_UNQUOTED_STRING)
  			goto parse_error;
  		if (token == GUC_STRING)	/* strip quotes and escapes */
+ 		{
  			opt_value = GUC_scanstr(yytext);
+ 			is_string = true;
+ 		}
  		else
  			opt_value = pstrdup(yytext);
  
***************
*** 620,625 **** ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
--- 624,630 ----
  			item = palloc(sizeof *item);
  			item->name = opt_name;
  			item->value = opt_value;
+ 			item->value_is_string = is_string;
  			item->filename = pstrdup(config_file);
  			item->sourceline = ConfigFileLineno-1;
  			item->next = NULL;
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
***************
*** 5105,5110 **** config_enum_get_options(struct config_enum * record, const char *prefix,
--- 5105,5260 ----
  	return retstr.data;
  }
  
+ /*given key and value validate the config value*/
+ 
+ struct config_generic *
+ validate_conf_option(const char *name, const char *value)
+ {
+ 	struct config_generic *record;
+ 
+ 	record = find_option(name, true, LOG);
+ 	if (record == NULL)
+ 	{
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_UNDEFINED_OBJECT),
+ 			   errmsg("unrecognized configuration parameter \"%s\"", name)));
+ 	}
+ 
+ 	if (record->context == PGC_INTERNAL)
+ 	{
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
+ 				 errmsg("parameter \"%s\" cannot be changed",
+ 						name)));
+ 	}
+ 
+ 	/*
+ 	 * Evaluate value and set variable.
+ 	 */
+ 	switch (record->vartype)
+ 	{
+ 
+ 		case PGC_BOOL:
+ 			{
+ 				struct config_bool *conf = (struct config_bool *) record;
+ 				bool		newval;
+ 				void	   *newextra = NULL;
+ 
+ 				if (value)
+ 				{
+ 					if (!parse_bool(value, &newval))
+ 					{
+ 						ereport(ERROR,
+ 								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 						  errmsg("parameter \"%s\" requires a Boolean value",
+ 								 name)));
+ 					}
+ 					if (!call_bool_check_hook(conf, &newval, &newextra,
+ 											  PGC_S_FILE, LOG))
+ 						return NULL;
+ 				}
+ 			}
+ 			break;
+ 
+ 		case PGC_INT:
+ 			{
+ 				struct config_int *conf = (struct config_int *) record;
+ 				int			newval;
+ 				void	   *newextra = NULL;
+ 
+ 				if (value)
+ 				{
+ 					const char *hintmsg;
+ 
+ 					if (!parse_int(value, &newval, conf->gen.flags, &hintmsg))
+ 					{
+ 						ereport(ERROR,
+ 								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 						 errmsg("invalid value for parameter \"%s\": \"%s\"",
+ 								name, value),
+ 								 hintmsg ? errhint("%s", _(hintmsg)) : 0));
+ 					}
+ 					if (newval < conf->min || newval > conf->max)
+ 					{
+ 						ereport(ERROR,
+ 								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 								 errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)",
+ 										newval, name, conf->min, conf->max)));
+ 					}
+ 					if (!call_int_check_hook(conf, &newval, &newextra,
+ 											 PGC_S_FILE, LOG))
+ 						return NULL;
+ 				}
+ 			}
+ 
+ 			break;
+ 
+ 		case PGC_REAL:
+ 			{
+ 				struct config_real *conf = (struct config_real *) record;
+ 				double		newval;
+ 				void	   *newextra = NULL;
+ 
+ 				if (value)
+ 				{
+ 					if (!parse_real(value, &newval))
+ 					{
+ 						ereport(ERROR,
+ 								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 						  errmsg("parameter \"%s\" requires a numeric value",
+ 								 name)));
+ 					}
+ 					if (newval < conf->min || newval > conf->max)
+ 					{
+ 						ereport(ERROR,
+ 								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 								 errmsg("%g is outside the valid range for parameter \"%s\" (%g .. %g)",
+ 										newval, name, conf->min, conf->max)));
+ 					}
+ 					if (!call_real_check_hook(conf, &newval, &newextra,
+ 											  PGC_S_FILE, LOG))
+ 						return NULL;
+ 				}
+ 			}
+ 
+ 			break;
+ 
+ 		case PGC_STRING:
+ 			{
+ 				struct config_string *conf = (struct config_string *) record;
+ 				char	   *newval;
+ 				void	   *newextra = NULL;
+ 
+ 				if (value)
+ 				{
+ 					/*
+ 					 * The value passed by the caller could be transient, so
+ 					 * we always strdup it.
+ 					 */
+ 					newval = guc_strdup(LOG, value);
+ 					if (newval == NULL)
+ 						return NULL;
+ 
+ 					/*
+ 					 * The only built-in "parsing" check we have is to apply
+ 					 * truncation if GUC_IS_NAME.
+ 					 */
+ 					if (conf->gen.flags & GUC_IS_NAME)
+ 						truncate_identifier(newval, strlen(newval), true);
+ 
+ 					if (!call_string_check_hook(conf, &newval, &newextra,
+ 												PGC_S_FILE, LOG))
+ 					{
+ 						free(newval);
+ 						return NULL;
+ 					}
+ 				}
+ 			}
+ 	}
+ 
+ 	return record;
+ }
+ 
  
  /*
   * Sets option `name' to given value.
*** a/src/bin/initdb/initdb.c
--- b/src/bin/initdb/initdb.c
***************
*** 177,182 **** static const char *backend_options = "--single -F -O -c search_path=pg_catalog -
--- 177,183 ----
  static char bin_path[MAXPGPATH];
  static char backend_exec[MAXPGPATH];
  
+ char	   *make_absolute_path(const char *path);
  static void *pg_malloc(size_t size);
  static char *pg_strdup(const char *s);
  static char **replace_token(char **lines,
***************
*** 1163,1168 **** setup_config(void)
--- 1164,1171 ----
  	char		repltok[MAXPGPATH];
  	char		path[MAXPGPATH];
  	const char *default_timezone;
+ 	char	   *abs_data_dir;
+ 	FILE	   *autofile;
  
  	fputs(_("creating configuration files ... "), stdout);
  	fflush(stdout);
***************
*** 1245,1255 **** setup_config(void)
--- 1248,1284 ----
  		conflines = replace_token(conflines, "#log_timezone = 'GMT'", repltok);
  	}
  
+ 	abs_data_dir = make_absolute_path(pg_data);
+ 
+ 	snprintf(repltok, sizeof(repltok), "include_dir = '%s/config_dir'",
+ 			 abs_data_dir);
+ 	conflines = replace_token(conflines, "#include_dir = 'conf.d'", repltok);
+ 
  	snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
  
  	writefile(path, conflines);
  	chmod(path, S_IRUSR | S_IWUSR);
  
+ 	/* create a .auto for conf file */
+ 	sprintf(path, "%s/config_dir/postgresql.auto.conf", pg_data);
+ 	autofile = fopen(path, PG_BINARY_W);
+ 	if (autofile == NULL)
+ 	{
+ 		fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
+ 				progname, path, strerror(errno));
+ 		exit_nicely();
+ 	}
+ 
+ 	if (fclose(autofile))
+ 	{
+ 		fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
+ 				progname, path, strerror(errno));
+ 		exit_nicely();
+ 	}
+ 
+ 	chmod(path, S_IRUSR | S_IWUSR);
+ 
+ 
  	free(conflines);
  
  
***************
*** 2823,2828 **** check_need_password(const char *authmethodlocal, const char *authmethodhost)
--- 2852,2933 ----
  	}
  }
  
+ /*
+  * If the given pathname isn't already absolute, make it so, interpreting
+  * it relative to the current working directory.
+  *
+  * Also canonicalizes the path.  The result is always a malloc'd copy.
+  *
+  */
+ char *
+ make_absolute_path(const char *path)
+ {
+ 	char	   *new;
+ 
+ 	/* Returning null for null input is convenient for some callers */
+ 	if (path == NULL)
+ 		return NULL;
+ 
+ 	if (!is_absolute_path(path))
+ 	{
+ 		char	   *buf;
+ 		size_t		buflen;
+ 
+ 		buflen = MAXPGPATH;
+ 		for (;;)
+ 		{
+ 			buf = malloc(buflen);
+ 			if (!buf)
+ 			{
+ 				fprintf(stderr, _("%s: Memory allocation failed\n"),
+ 						progname);
+ 				exit_nicely();
+ 			}
+ 
+ 			if (getcwd(buf, buflen))
+ 				break;
+ 			else if (errno == ERANGE)
+ 			{
+ 				free(buf);
+ 				buflen *= 2;
+ 				continue;
+ 			}
+ 			else
+ 			{
+ 				free(buf);
+ 				fprintf(stderr, _("%s: could not get current working directory\n"),
+ 						progname);
+ 				exit_nicely();
+ 			}
+ 		}
+ 
+ 		new = malloc(strlen(buf) + strlen(path) + 2);
+ 		if (!new)
+ 		{
+ 			fprintf(stderr, _("%s: Memory allocation failed\n"),
+ 					progname);
+ 			exit_nicely();
+ 		}
+ 		sprintf(new, "%s/%s", buf, path);
+ 		free(buf);
+ 	}
+ 	else
+ 	{
+ 		new = strdup(path);
+ 		if (!new)
+ 		{
+ 			fprintf(stderr, _("%s: Memory allocation failed\n"),
+ 					progname);
+ 			exit_nicely();
+ 		}
+ 	}
+ 
+ 	/* Make sure punctuation is canonical, too */
+ 	canonicalize_path(new);
+ 
+ 	return new;
+ }
+ 
  int
  main(int argc, char *argv[])
  {
***************
*** 2887,2893 **** main(int argc, char *argv[])
  		"base",
  		"base/1",
  		"pg_tblspc",
! 		"pg_stat_tmp"
  	};
  
  	progname = get_progname(argv[0]);
--- 2992,2999 ----
  		"base",
  		"base/1",
  		"pg_tblspc",
! 		"pg_stat_tmp",
! 		"config_dir"
  	};
  
  	progname = get_progname(argv[0]);
*** a/src/include/commands/dbcommands.h
--- b/src/include/commands/dbcommands.h
***************
*** 58,63 **** extern void RenameDatabase(const char *oldname, const char *newname);
--- 58,64 ----
  extern void AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel);
  extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt);
  extern void AlterDatabaseOwner(const char *dbname, Oid newOwnerId);
+ extern void set_config_file(VariableSetStmt *setstmt);
  
  extern Oid	get_database_oid(const char *dbname, bool missingok);
  extern char *get_database_name(Oid dbid);
***************
*** 67,70 **** extern void dbase_desc(StringInfo buf, uint8 xl_info, char *rec);
--- 68,73 ----
  
  extern void check_encoding_locale_matches(int encoding, const char *collate, const char *ctype);
  
+ extern void AtEOXact_UpdateAutoConfFiles(bool isCommit);
+ 
  #endif   /* DBCOMMANDS_H */
*** a/src/include/nodes/parsenodes.h
--- b/src/include/nodes/parsenodes.h
***************
*** 1425,1430 **** typedef struct VariableSetStmt
--- 1425,1431 ----
  	char	   *name;			/* variable to be set */
  	List	   *args;			/* List of A_Const nodes */
  	bool		is_local;		/* SET LOCAL? */
+ 	bool		is_persistent;		/* SET PERSISTENT? */	
  } VariableSetStmt;
  
  /* ----------------------
*** a/src/include/parser/kwlist.h
--- b/src/include/parser/kwlist.h
***************
*** 279,284 **** PG_KEYWORD("partial", PARTIAL, UNRESERVED_KEYWORD)
--- 279,285 ----
  PG_KEYWORD("partition", PARTITION, UNRESERVED_KEYWORD)
  PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD)
  PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD)
+ PG_KEYWORD("persistent", PERSISTENT, UNRESERVED_KEYWORD)
  PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD)
  PG_KEYWORD("plans", PLANS, UNRESERVED_KEYWORD)
  PG_KEYWORD("position", POSITION, COL_NAME_KEYWORD)
*** a/src/include/utils/guc.h
--- b/src/include/utils/guc.h
***************
*** 105,110 **** typedef struct ConfigVariable
--- 105,111 ----
  {
  	char	   *name;
  	char	   *value;
+ 	int			value_is_string;
  	char	   *filename;
  	int			sourceline;
  	struct ConfigVariable *next;
***************
*** 191,196 **** typedef enum
--- 192,201 ----
  
  #define GUC_NOT_WHILE_SEC_REST	0x8000	/* can't set if security restricted */
  
+ /* postgresql.auto.file name and its lock */
+ #define AutoConfigFileName "config_dir/postgresql.auto.conf"
+ #define CONF_LOCK_POSTFIX  ".lock"
+ 
  /* GUC vars that are actually declared in guc.c, rather than elsewhere */
  extern bool log_duration;
  extern bool Debug_print_plan;
*** a/src/include/utils/guc_tables.h
--- b/src/include/utils/guc_tables.h
***************
*** 260,265 **** extern void build_guc_variables(void);
--- 260,267 ----
  extern const char *config_enum_lookup_by_value(struct config_enum * record, int val);
  extern bool config_enum_lookup_by_name(struct config_enum * record,
  						   const char *value, int *retval);
+ extern struct config_generic * validate_conf_option(const char *name,
+ 								const char *value);
  
  
  #endif   /* GUC_TABLES_H */
