*** a/src/backend/commands/dbcommands.c
--- b/src/backend/commands/dbcommands.c
***************
*** 58,63 ****
--- 58,80 ----
  #include "utils/snapmgr.h"
  #include "utils/syscache.h"
  #include "utils/tqual.h"
+ #include "utils/guc_tables.h"
+ 
+ 
+ /*lock file used in edit postgresql.conf.auto*/
+ struct lock_file 
+ {
+ 	int fd;
+ 	char filename[MAXPGPATH];
+ };
+ 
+ 
+ struct strbuf 
+ {
+ 	size_t len;
+ 	char *buf;
+ };
+ 
  
  
  typedef struct
***************
*** 1434,1439 **** AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
--- 1451,1827 ----
  
  
  /*
+  * EDIT .AUTO.CONF FILE WITH FUNCTION pg_change_conf(key,value)...
+  */
+ 
+ /*create a .lock file for .auto.conf file so that it act as an lock to prevent concurrent edit on .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, 0666);
+ 	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 .lock file*/
+ int close_lock_file(struct lock_file *lk)
+ {
+ 	int fd = lk->fd;
+ 	lk->fd = -1;
+ 	return close(fd);
+ }
+ 
+ /*function to commit the changes done on element of .auto.conf file */
+ /* here we rename .lock to .auto.conf hence commit the changes to .auto.conf file */
+ 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 some error we need to rollback the changes we do this by removing .lock file*/
+ 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;
+ }
+ 
+ 
+ /*
+  * get the lines from a text file
+  */
+ static char **
+ readfile(const char *path)
+ {
+ 	FILE	   *infile;
+ 	int			maxlength = 1,
+ 				linelen = 0;
+ 	int			nlines = 0;
+ 	char	  **result;
+ 	char	   *buffer;
+ 	int			c;
+ 
+ 	if ((infile = fopen(path, "r")) == NULL)
+ 	{
+ 		ereport(ERROR,
+ 			(errmsg("failed to read into to \"postgresql.auto.conf\" file")));
+ 		/*throw error*/
+ 	}
+ 
+ 	/* pass over the file twice - the first time to size the result */
+ 
+ 	while ((c = fgetc(infile)) != EOF)
+ 	{
+ 		linelen++;
+ 		if (c == '\n')
+ 		{
+ 			nlines++;
+ 			if (linelen > maxlength)
+ 				maxlength = linelen;
+ 			linelen = 0;
+ 		}
+ 	}
+ 
+ 	/* handle last line without a terminating newline (yuck) */
+ 	if (linelen)
+ 		nlines++;
+ 	if (linelen > maxlength)
+ 		maxlength = linelen;
+ 
+ 	/* set up the result and the line buffer */
+ 	result = (char **) palloc((nlines + 1) * sizeof(char *));
+ 	buffer = (char *) palloc(maxlength + 1);
+ 
+ 	/* now reprocess the file and store the lines */
+ 	rewind(infile);
+ 	nlines = 0;
+ 	while (fgets(buffer, maxlength + 1, infile) != NULL)
+ 		result[nlines++] = pstrdup(buffer);
+ 
+ 	fclose(infile);
+ 	pfree(buffer);
+ 	result[nlines] = NULL;
+ 
+ 	return result;
+ }
+ 
+ /*
+  * write an array of lines to a file 
+  * used to write the in-memory of .auto.conf elements to .lock file
+  *
+  */
+ static void
+ writeAutoConffile(int fd, char **lines)
+ {
+ 	char	  **line;
+ 
+ 	for (line = lines; *line != NULL; line++)
+ 	{
+ 		if (write(fd, *line, strlen(*line)) < 0)
+ 		{
+ 			ereport(ERROR,
+ 			(errmsg("failed to write into to \"postgresql.auto.conf.lock\" file")));
+ 			/*throw error*/
+ 		}
+ 		pfree(*line);
+ 	}
+ 
+ 	if (pg_fsync(fd) != 0)
+ 	{
+ 		ereport(ERROR,
+ 				(errcode_for_file_access(),
+ 				 errmsg("could not write to file \"postgresql.auto.conf.lock\": %m")));
+ 	}
+ 
+ }
+ 
+ /*
+  * make the changes requested by pg_change_conf() In-Memory by replacing the older content.
+  * If not already exist add the new (key,value) to end of list.
+  */
+ static char **
+ replace_autoline(char **lines,unsigned int repl_lineno , const char *replacement,
+ 					bool hasmatch)
+ {
+ 	int			numlines = 1;
+ 	int			i;
+ 	char	  **result;
+ 	int		replen;
+ 	char	   *newline;
+ 
+ 	for (i = 0; lines[i]; i++)
+ 	{
+ 		numlines++;
+ 	}
+ 
+ 	if (!hasmatch)
+ 	{
+ 	       /*key not found need to add one more line at the end*/
+ 		result = (char **) palloc0((numlines + 1)* sizeof(char *));
+ 		repl_lineno++;
+ 	}
+ 	else
+ 	{
+ 		result = (char **) palloc0(numlines * sizeof(char *));
+ 	}	
+ 
+ 	replen = strlen(replacement);
+ 	
+ 	for (i = 0; i < numlines; i++)
+ 	{
+ 		/* just copy pointer if NULL or no change needed */
+ 		if (lines[i] == NULL || (i != repl_lineno - 1))
+ 		{
+ 			result[i] = lines[i];
+ 			continue;
+ 		}
+ 
+ 		/* if we get here a change is needed - set up new line */
+ 
+ 		newline = (char *) palloc(replen + 1);
+ 
+ 		strcpy(newline, replacement);
+ 		result[i] = newline;
+ 	}
+ 
+ 	if (!hasmatch)
+ 	{
+ 		/*key not found in file add it to end of (key,value) list*/
+ 		newline = (char *) palloc(replen + 1);
+ 
+ 		strcpy(newline, replacement);
+ 		result[i - 1] = newline;
+ 	}
+ 	
+ 	return result;
+ }
+ 
+ 
+ /*main function which edit .auto.file with given (key,value) input*/
+ void set_config_file(VariableSetStmt *setstmt)
+ {   
+        struct strbuf sb;
+ 	char *key;
+ 	char *value;
+ 	char	  **conflines;
+ 	struct lock_file *lock = NULL;
+ 	int fd = -1, lineno = 0;
+ 	FILE	   *infile;
+ 	struct config_generic *record;
+ 	char		abs_path[MAXPGPATH];
+ 	bool OK;
+ 	bool hasmatch;
+ 
+ 
+ 	if  (IsTransactionBlock())
+ 	{
+ 		ereport(ERROR,
+ 		(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
+ 		 errmsg("cannot modify autoconf file inside a transaction")));
+ 	}
+ 
+ 	if (!superuser())
+ 	{
+ 		ereport(ERROR,
+ 					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ 					 (errmsg("must be superuser to edit postgresql.conf"))));
+ 	}
+ 	
+ 	/*1. validate the key and value and then make the conf info into (key, value, comment) pair*/
+ 
+ 	key = pstrdup(setstmt->name); 	
+ 	value = ExtractSetVariableArgs(setstmt);
+ 	
+ 	record = validate_conf_option(key,value);
+ 
+ 	if (!record)
+ 	{
+ 		ereport(ERROR,
+ 		(errmsg("evaluation of config:values failed")));
+ 	}
+ 	
+ 	sb.len = strlen(key);
+ 	sb.len += strlen(value);
+ 	sb.buf = palloc(sb.len + 100);
+ 
+     	if (record->vartype == PGC_STRING)
+ 	{
+ 		snprintf(sb.buf, sb.len + 100, "%s = '%s' \n", key, value);
+ 	}
+ 	else
+ 	{
+ 		snprintf(sb.buf, sb.len + 100, "%s = %s \n", key, value);
+ 	}
+ 	
+ 	/*2. create the lock file */
+ 
+ 	join_path_components(abs_path, data_directory, AutoConfigFileName);
+ 	canonicalize_path(abs_path);
+ 
+ 	PG_TRY();
+ 	{	
+ 		lock = palloc0(sizeof(struct lock_file));
+ 
+ 		/*take the .lock file so other backends are restricted from access*/
+ 		fd = lock_confile(lock, abs_path, 0);
+ 		if (fd < 0) 
+ 		{
+ 			ereport(ERROR,
+ 				(errmsg("lock file creation failed")));	}
+ 
+ 		/*open .auto.conf file*/
+ 		infile = fopen(abs_path, "r");
+ 		if (infile == NULL) 
+ 		{
+ 			ereport(ERROR,
+ 				(errmsg("failed to open postgresql.auto.conf file")));
+ 		} 
+ 		
+ 
+ 		/*3. read from the auto.conf file and write new contents to .lock file */
+ 		conflines = readfile(abs_path);
+ 
+ 		OK = ParseAutoConfigFp(infile, abs_path, key, &lineno, -1, LOG, &hasmatch);
+ 		if (!OK)
+ 		{			
+ 			ereport(ERROR,
+ 				(errmsg("parsing failed for postgresql.auto.conf file")));
+ 			/*throw error*/
+ 		}
+ 
+ 		fclose(infile);
+ 		conflines = replace_autoline(conflines, lineno - 1, sb.buf, hasmatch);
+ 
+ 		/*Write the New contents to .lock file*/
+ 		writeAutoConffile(fd, conflines);
+ 
+ 
+ 		/*4. commit the .lock file;  here rename the lock file to .auto.conf file*/
+ 		
+ 		if (commit_lock_file(lock) < 0) 
+ 		{ 			
+ 			ereport(ERROR,
+ 			(errmsg("commiting lock.postgresql.auto.conf failed")));
+ 		}
+ 	}
+ 	PG_CATCH()
+ 	{
+ 		if (lock)
+ 		{
+ 			/*remove the .lock file*/
+ 			rollback_lock_file(lock);
+ 			pfree(lock);
+ 		}
+ 
+ 		PG_RE_THROW();
+ 	}	
+ 	PG_END_TRY();
+ 	
+ 	pfree(lock);
+ 	return;				
+ }
+ 
+ 
+ 
+ 
+ /*
   * ALTER DATABASE name OWNER TO newowner
   */
  void
*** 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,1176 ----
  	 */
  	RemovePgTempFiles();
  
+ 	/*Remove .auto.conf.lock file make be left over from last crash*/
+ 
+ 	/*get .auto.conf.lock file name */
+ 	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
***************
*** 1061,1067 **** standard_ProcessUtility(Node *parsetree,
  		case T_AlterDatabaseSetStmt:
  			/* no event triggers for global objects */
  			AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
! 			break;
  
  		case T_DropdbStmt:
  			{
--- 1061,1067 ----
  		case T_AlterDatabaseSetStmt:
  			/* no event triggers for global objects */
  			AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
! 			break;		
  
  		case T_DropdbStmt:
  			{
***************
*** 2061,2067 **** CreateCommandTag(Node *parsetree)
  		case T_AlterDatabaseSetStmt:
  			tag = "ALTER DATABASE";
  			break;
! 
  		case T_DropdbStmt:
  			tag = "DROP DATABASE";
  			break;
--- 2061,2067 ----
  		case T_AlterDatabaseSetStmt:
  			tag = "ALTER DATABASE";
  			break;
! 			
  		case T_DropdbStmt:
  			tag = "DROP DATABASE";
  			break;
*** a/src/backend/utils/adt/misc.c
--- b/src/backend/utils/adt/misc.c
***************
*** 194,199 **** pg_reload_conf(PG_FUNCTION_ARGS)
--- 194,221 ----
  
  
  /*
+  * pg_change_conf: function to write in conf file
+  *
+  */
+ Datum
+ pg_change_conf(PG_FUNCTION_ARGS)
+ {
+ 	char	   *key = PG_GETARG_CSTRING(0);
+ 	char    *value = PG_GETARG_CSTRING(1);
+ 	VariableSetStmt setstmt;
+ 	A_Const *n = makeNode(A_Const);
+ 	n->val.type = T_String;
+ 	n->val.val.str = value;
+ 	n->location = -1;	
+ 	setstmt.type = T_VariableSetStmt;
+ 	setstmt.kind = VAR_SET_VALUE;
+ 	setstmt.name = key;
+ 	setstmt.args = list_make1(n);	
+ 	set_config_file(&setstmt);
+ 	PG_RETURN_BOOL(true);
+ }
+ 
+ /*
   * Rotate log file
   */
  Datum
*** a/src/backend/utils/misc/guc-file.l
--- b/src/backend/utils/misc/guc-file.l
***************
*** 468,473 **** GUC_flex_fatal(const char *msg)
--- 468,609 ----
  	return 0;	/* keep compiler quiet */
  }
  
+ /**
+ *  Parse the config file and return the line number which matched the key(name)
+ **/
+ 
+ bool
+ ParseAutoConfigFp(FILE *fp, const char *config_file, char * name, int *line_no, int depth, int elevel,
+ 			  			bool *hasmatch)
+ {
+ 	volatile bool OK = true;
+ 	unsigned int save_ConfigFileLineno = ConfigFileLineno;
+ 	sigjmp_buf *save_GUC_flex_fatal_jmp = GUC_flex_fatal_jmp;
+ 	sigjmp_buf	flex_fatal_jmp;
+ 	volatile YY_BUFFER_STATE lex_buffer = NULL;
+ 	int			errorcount;
+ 	int			token;
+ 
+ 	if (sigsetjmp(flex_fatal_jmp, 1) == 0)
+ 		GUC_flex_fatal_jmp = &flex_fatal_jmp;
+ 	else
+ 	{
+ 		/*
+ 		 * Regain control after a fatal, internal flex error.  It may have
+ 		 * corrupted parser state.  Consequently, abandon the file, but trust
+ 		 * that the state remains sane enough for GUC_yy_delete_buffer().
+ 		 */
+ 		elog(elevel, "%s at file \"%s\" line %u",
+ 			 GUC_flex_fatal_errmsg, config_file, ConfigFileLineno);
+ 
+ 		OK = false;
+ 		goto cleanup;
+ 	}
+ 
+ 	/*
+ 	 * Parse
+ 	 */
+ 	ConfigFileLineno = 1;
+ 	errorcount = 0;
+ 	*hasmatch = false;
+ 
+ 	lex_buffer = GUC_yy_create_buffer(fp,YY_BUF_SIZE);
+ 	GUC_yy_switch_to_buffer(lex_buffer);
+ 
+ 	/* This loop iterates once per logical line */
+ 	while ((token = GUC_yylex()))
+ 	{
+ 		char	   *opt_name = NULL;		
+ 
+ 		if (token == GUC_EOL)	/* empty or comment line */
+ 			continue;
+ 
+ 		/* first token on line is option name */
+ 		if (token != GUC_ID && token != GUC_QUALIFIED_ID)
+ 			goto parse_error;
+ 		opt_name = pstrdup(GUC_yytext);
+ 
+ 		/* next we have an optional equal sign; discard if present */
+ 		token = GUC_yylex();
+ 		if (token == GUC_EQUALS)
+ 			token = GUC_yylex();
+ 		
+ 		/* now we'd like an end of line, or possibly EOF */
+ 		token = GUC_yylex();
+ 		if (token != GUC_EOL)
+ 		{
+ 			if (token != 0)
+ 				goto parse_error;
+ 			/* treat EOF like \n for line numbering purposes, cf bug 4752 */
+ 			ConfigFileLineno++;
+ 		}
+ 
+ 		/* OK, process the option name and value */
+ 		if ((guc_name_compare(opt_name, name) == 0))
+ 		{
+ 			*hasmatch = true;
+ 			break;
+ 		}
+ 		else if (token == 0)
+ 		{
+ 			break;
+ 		}
+ 		
+ 		continue;
+ 
+ 	parse_error:
+ 		/* release storage if we allocated any on this line */
+ 		if (opt_name)
+ 			pfree(opt_name);
+ 
+ 		/* report the 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, GUC_yytext)));
+ 		OK = false;
+ 		errorcount++;
+ 
+ 		/*
+ 		 * To avoid producing too much noise when fed a totally bogus file,
+ 		 * give up after 100 syntax errors per file (an arbitrary number).
+ 		 * Also, if we're only logging the errors at DEBUG level anyway,
+ 		 * might as well give up immediately.  (This prevents postmaster
+ 		 * children from bloating the logs with duplicate complaints.)
+ 		 */
+ 		if (errorcount >= 100 || elevel <= DEBUG1)
+ 		{
+ 			ereport(elevel,
+ 					(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ 					 errmsg("too many syntax errors found, abandoning file \"%s\"",
+ 							config_file)));
+ 			break;
+ 		}
+ 
+ 		/* resync to next end-of-line or EOF */
+ 		while (token != GUC_EOL && token != 0)
+ 			token = GUC_yylex();
+ 		/* break out of loop on EOF */
+ 		if (token == 0)
+ 			break;
+ 	}
+ 
+ cleanup:
+ 	GUC_yy_delete_buffer(lex_buffer);
+ 	/* Each recursion level must save and restore these static variables. */
+ 	*line_no = ConfigFileLineno;
+ 	ConfigFileLineno = save_ConfigFileLineno;
+ 	GUC_flex_fatal_jmp = save_GUC_flex_fatal_jmp;
+ 	return OK;
+ }
+ 
+ 
  /*
   * Read and parse a single configuration file.  This function recurses
   * to handle "include" directives.
*** 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/backend/utils/misc/postgresql.conf.sample
--- b/src/backend/utils/misc/postgresql.conf.sample
***************
*** 30,36 ****
  #                                                   h   = hours
  #                                                   d   = days
  
- 
  #------------------------------------------------------------------------------
  # FILE LOCATIONS
  #------------------------------------------------------------------------------
--- 30,35 ----
*** 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];
  
+ static 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,1285 ----
  		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)
--- 2853,2934 ----
  	}
  }
  
+ /*
+  * 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.
+  *
+  */
+ static 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]);
--- 2993,3000 ----
  		"base",
  		"base/1",
  		"pg_tblspc",
! 		"pg_stat_tmp",
! 		"config_dir"
  	};
  
  	progname = get_progname(argv[0]);
*** a/src/include/access/xlog_internal.h
--- b/src/include/access/xlog_internal.h
***************
*** 255,260 **** extern void XLogArchiveCleanup(const char *xlog);
--- 255,261 ----
  /*
   * These aren't in xlog.h because I'd rather not include fmgr.h there.
   */
+ 
  extern Datum pg_start_backup(PG_FUNCTION_ARGS);
  extern Datum pg_stop_backup(PG_FUNCTION_ARGS);
  extern Datum pg_switch_xlog(PG_FUNCTION_ARGS);
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 3005,3010 **** DATA(insert OID = 2625 ( pg_ls_dir			PGNSP PGUID 12 1 1000 0 0 f f f f t t v 1 0
--- 3005,3012 ----
  DESCR("list all files in a directory");
  DATA(insert OID = 2626 ( pg_sleep			PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 2278 "701" _null_ _null_ _null_ _null_ pg_sleep _null_ _null_ _null_ ));
  DESCR("sleep for the specified time in seconds");
+ DATA(insert OID = 2634 ( pg_change_conf     PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 16 "2275 2275" _null_ _null_ _null_ _null_ pg_change_conf _null_ _null_ _null_ ));
+ DESCR("changes a parameter in .auto.conf file");
  
  DATA(insert OID = 2971 (  text				PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "16" _null_ _null_ _null_ _null_ booltext _null_ _null_ _null_ ));
  DESCR("convert boolean to text");
*** 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);
*** a/src/include/nodes/parsenodes.h
--- b/src/include/nodes/parsenodes.h
***************
*** 2361,2366 **** typedef struct AlterDatabaseSetStmt
--- 2361,2368 ----
  	VariableSetStmt *setstmt;	/* SET or RESET subcommand */
  } AlterDatabaseSetStmt;
  
+ 
+ 
  /* ----------------------
   *		Dropdb Statement
   * ----------------------
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 482,487 **** extern Datum pg_sleep(PG_FUNCTION_ARGS);
--- 482,488 ----
  extern Datum pg_get_keywords(PG_FUNCTION_ARGS);
  extern Datum pg_typeof(PG_FUNCTION_ARGS);
  extern Datum pg_collation_for(PG_FUNCTION_ARGS);
+ extern Datum pg_change_conf(PG_FUNCTION_ARGS);
  
  /* oid.c */
  extern Datum oidin(PG_FUNCTION_ARGS);
*** a/src/include/utils/guc.h
--- b/src/include/utils/guc.h
***************
*** 191,196 **** typedef enum
--- 191,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;
***************
*** 329,334 **** extern void SetPGVariable(const char *name, List *args, bool is_local);
--- 334,343 ----
  extern void GetPGVariable(const char *name, DestReceiver *dest);
  extern TupleDesc GetPGVariableResultDesc(const char *name);
  
+ extern bool
+ ParseAutoConfigFp(FILE *fp, const char *config_file, char * name, int *line_no, int depth, int elevel,
+ 			  			bool *hasmatch);
+ 
  extern void ExecSetVariableStmt(VariableSetStmt *stmt);
  extern char *ExtractSetVariableArgs(VariableSetStmt *stmt);
  
*** 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 */
