diff -durpN postgresql/doc/src/sgml/keywords.sgml postgresql.2/doc/src/sgml/keywords.sgml
--- postgresql/doc/src/sgml/keywords.sgml	2012-08-08 06:26:48.824119524 +0200
+++ postgresql.2/doc/src/sgml/keywords.sgml	2013-01-18 21:01:48.879276633 +0100
@@ -3388,6 +3388,13 @@
     <entry></entry>
    </row>
    <row>
+    <entry><token>PERSISTENT</token></entry>
+    <entry>non-reserved</entry>
+    <entry></entry>
+    <entry></entry>
+    <entry></entry>
+   </row>
+   <row>
     <entry><token>PLACING</token></entry>
     <entry>reserved</entry>
     <entry>non-reserved</entry>
diff -durpN postgresql/doc/src/sgml/ref/set.sgml postgresql.2/doc/src/sgml/ref/set.sgml
--- postgresql/doc/src/sgml/ref/set.sgml	2012-04-16 19:57:22.233913109 +0200
+++ postgresql.2/doc/src/sgml/ref/set.sgml	2013-01-18 18:35:17.758223569 +0100
@@ -21,8 +21,8 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-SET [ SESSION | LOCAL ] <replaceable class="PARAMETER">configuration_parameter</replaceable> { TO | = } { <replaceable class="PARAMETER">value</replaceable> | '<replaceable class="PARAMETER">value</replaceable>' | DEFAULT }
-SET [ SESSION | LOCAL ] TIME ZONE { <replaceable class="PARAMETER">timezone</replaceable> | LOCAL | DEFAULT }
+SET [ SESSION | LOCAL | PERSISTENT ] <replaceable class="PARAMETER">configuration_parameter</replaceable> { TO | = } { <replaceable class="PARAMETER">value</replaceable> | '<replaceable class="PARAMETER">value</replaceable>' | DEFAULT }
+SET [ SESSION | LOCAL | PERSISTENT ] TIME ZONE { <replaceable class="PARAMETER">timezone</replaceable> | LOCAL | DEFAULT }
 </synopsis>
  </refsynopsisdiv>
 
@@ -50,6 +50,16 @@ SET [ SESSION | LOCAL ] TIME ZONE { <rep
   </para>
 
   <para>
+   <command>SET PERSISTENT</command> writes the configuration parameter
+   values to the <filename>postgresql.auto.conf</filename> file. With
+   <literal>DEFAULT</literal>, it writes the default configuration parameter
+   values to the <filename>postgresql.auto.conf</filename> file. For removing
+   a configuration entry from <filename>postgresql.auto.conf</filename> file,
+   use <command>RESET PERSISTENT</command>. The values will be effective
+   after reload of server configuration (SIGHUP) or server startup.
+  </para>
+  
+  <para>
    The effects of <command>SET LOCAL</command> last only till the end of
    the current transaction, whether committed or not.  A special case is
    <command>SET</command> followed by <command>SET LOCAL</command> within
@@ -98,8 +108,8 @@ SET [ SESSION | LOCAL ] TIME ZONE { <rep
     <listitem>
      <para>
       Specifies that the command takes effect for the current session.
-      (This is the default if neither <literal>SESSION</> nor
-      <literal>LOCAL</> appears.)
+      (This is the default option, if any of <literal>SESSION</>, 
+      <literal>LOCAL</> or <literal>PERSISTENT</> are not provided.)
      </para>
     </listitem>
    </varlistentry>
@@ -119,6 +129,18 @@ SET [ SESSION | LOCAL ] TIME ZONE { <rep
    </varlistentry>
 
    <varlistentry>
+    <term><literal>PERSISTENT</></term>
+    <listitem>
+     <para>
+      Writes updated configuration parameters to <filename>postgresql.auto.conf</filename>.
+      These configuration parameters takes effect after reload of
+      configuration file (SIGHUP) or in next server start based on
+      the type of configuration parameter modified.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
     <term><replaceable class="PARAMETER">configuration_parameter</replaceable></term>
     <listitem>
      <para>
@@ -154,7 +176,7 @@ SET [ SESSION | LOCAL ] TIME ZONE { <rep
     <varlistentry>
      <term><literal>SCHEMA</literal></term>
      <listitem>
-      <para><literal>SET SCHEMA '<replaceable>value</>'</> is an alias for
+      <para><literal>SET [ PERSISTENT ] SCHEMA '<replaceable>value</>'</> is an alias for
        <literal>SET search_path TO <replaceable>value</></>.  Only one
        schema can be specified using this syntax.
       </para>
@@ -164,7 +186,7 @@ SET [ SESSION | LOCAL ] TIME ZONE { <rep
     <varlistentry>
      <term><literal>NAMES</literal></term>
      <listitem>
-      <para><literal>SET NAMES <replaceable>value</></> is an alias for
+      <para><literal>SET [ PERSISTENT ] NAMES <replaceable>value</></> is an alias for
        <literal>SET client_encoding TO <replaceable>value</></>.
       </para>
      </listitem>
@@ -192,7 +214,7 @@ SELECT setseed(<replaceable>value</repla
     <varlistentry>
      <term><literal>TIME ZONE</literal></term>
      <listitem>
-      <para><literal>SET TIME ZONE <replaceable>value</></> is an alias
+      <para><literal>SET [ PERSISTENT ] TIME ZONE <replaceable>value</></> is an alias
        for <literal>SET timezone TO <replaceable>value</></>.  The
        syntax <literal>SET TIME ZONE</literal> allows special syntax
        for the time zone specification.  Here are examples of valid
diff -durpN postgresql/src/backend/nodes/copyfuncs.c postgresql.2/src/backend/nodes/copyfuncs.c
--- postgresql/src/backend/nodes/copyfuncs.c	2013-01-02 09:19:03.729520424 +0100
+++ postgresql.2/src/backend/nodes/copyfuncs.c	2013-01-18 17:34:56.189963597 +0100
@@ -3264,6 +3264,7 @@ _copyVariableSetStmt(const VariableSetSt
 	COPY_STRING_FIELD(name);
 	COPY_NODE_FIELD(args);
 	COPY_SCALAR_FIELD(is_local);
+	COPY_SCALAR_FIELD(is_persistent);
 
 	return newnode;
 }
diff -durpN postgresql/src/backend/nodes/equalfuncs.c postgresql.2/src/backend/nodes/equalfuncs.c
--- postgresql/src/backend/nodes/equalfuncs.c	2013-01-02 09:19:03.740520544 +0100
+++ postgresql.2/src/backend/nodes/equalfuncs.c	2013-01-18 17:34:56.191963611 +0100
@@ -1555,6 +1555,7 @@ _equalVariableSetStmt(const VariableSetS
 	COMPARE_STRING_FIELD(name);
 	COMPARE_NODE_FIELD(args);
 	COMPARE_SCALAR_FIELD(is_local);
+	COMPARE_SCALAR_FIELD(is_persistent);
 
 	return true;
 }
diff -durpN postgresql/src/backend/parser/gram.y postgresql.2/src/backend/parser/gram.y
--- postgresql/src/backend/parser/gram.y	2013-01-02 09:19:03.777520949 +0100
+++ postgresql.2/src/backend/parser/gram.y	2013-01-18 17:34:56.197963653 +0100
@@ -394,7 +394,7 @@ static void processCASbits(int cas_bits,
 
 %type <istmt>	insert_rest
 
-%type <vsetstmt> set_rest set_rest_more SetResetClause FunctionSetResetClause
+%type <vsetstmt> set_rest set_rest_common set_rest_more SetResetClause FunctionSetResetClause
 
 %type <node>	TableElement TypedTableElement ConstraintElem TableFuncElement
 				ForeignTableElement
@@ -564,8 +564,8 @@ static void processCASbits(int cas_bits,
 	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
+	PARSER PARTIAL PARTITION PASSING PASSWORD PERSISTENT PLACING PLANS
+	POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY
 	PRIOR PRIVILEGES PROCEDURAL PROCEDURE
 
 	QUOTE
@@ -1293,6 +1293,12 @@ VariableSetStmt:
 					n->is_local = false;
 					$$ = (Node *) n;
 				}
+			| SET PERSISTENT set_rest_common
+				{
+					VariableSetStmt *n = $3;
+					n->is_persistent = true;
+					$$ = (Node *) n;
+				}
 		;
 
 set_rest:
@@ -1315,7 +1321,7 @@ set_rest:
 			| set_rest_more
 			;
 
-set_rest_more:	/* Generic SET syntaxes: */
+set_rest_common:	/* common SET syntaxes: */
 			var_name TO var_list
 				{
 					VariableSetStmt *n = makeNode(VariableSetStmt);
@@ -1346,13 +1352,6 @@ set_rest_more:	/* Generic SET syntaxes:
 					n->name = $1;
 					$$ = n;
 				}
-			| var_name FROM CURRENT_P
-				{
-					VariableSetStmt *n = makeNode(VariableSetStmt);
-					n->kind = VAR_SET_CURRENT;
-					n->name = $1;
-					$$ = n;
-				}
 			/* Special syntaxes mandated by SQL standard: */
 			| TIME ZONE zone_value
 				{
@@ -1365,14 +1364,6 @@ set_rest_more:	/* Generic SET syntaxes:
 						n->kind = VAR_SET_DEFAULT;
 					$$ = n;
 				}
-			| CATALOG_P Sconst
-				{
-					ereport(ERROR,
-							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-							 errmsg("current database cannot be changed"),
-							 parser_errposition(@2)));
-					$$ = NULL; /*not reached*/
-				}
 			| SCHEMA Sconst
 				{
 					VariableSetStmt *n = makeNode(VariableSetStmt);
@@ -1381,6 +1372,33 @@ set_rest_more:	/* Generic SET syntaxes:
 					n->args = list_make1(makeStringConst($2, @2));
 					$$ = n;
 				}
+			| XML_P OPTION document_or_content
+				{
+					VariableSetStmt *n = makeNode(VariableSetStmt);
+					n->kind = VAR_SET_VALUE;
+					n->name = "xmloption";
+					n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", @3));
+					$$ = n;
+				}
+			;
+
+set_rest_more:	/* Generic SET syntaxes: */
+			set_rest_common
+			| var_name FROM CURRENT_P
+				{
+					VariableSetStmt *n = makeNode(VariableSetStmt);
+					n->kind = VAR_SET_CURRENT;
+					n->name = $1;
+					$$ = n;
+				}
+			| CATALOG_P Sconst
+				{
+					ereport(ERROR,
+							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+							 errmsg("current database cannot be changed"),
+							 parser_errposition(@2)));
+					$$ = NULL; /*not reached*/
+				}
 			| NAMES opt_encoding
 				{
 					VariableSetStmt *n = makeNode(VariableSetStmt);
@@ -1415,14 +1433,6 @@ set_rest_more:	/* Generic SET syntaxes:
 					n->name = "session_authorization";
 					$$ = n;
 				}
-			| XML_P OPTION document_or_content
-				{
-					VariableSetStmt *n = makeNode(VariableSetStmt);
-					n->kind = VAR_SET_VALUE;
-					n->name = "xmloption";
-					n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", @3));
-					$$ = n;
-				}
 			/* Special syntaxes invented by PostgreSQL: */
 			| TRANSACTION SNAPSHOT Sconst
 				{
@@ -12590,6 +12600,7 @@ unreserved_keyword:
 			| PARTITION
 			| PASSING
 			| PASSWORD
+			| PERSISTENT
 			| PLANS
 			| PRECEDING
 			| PREPARE
diff -durpN postgresql/src/backend/postmaster/postmaster.c postgresql.2/src/backend/postmaster/postmaster.c
--- postgresql/src/backend/postmaster/postmaster.c	2013-01-03 11:25:47.350179404 +0100
+++ postgresql.2/src/backend/postmaster/postmaster.c	2013-01-18 17:34:56.200963674 +0100
@@ -1224,6 +1224,9 @@ PostmasterMain(int argc, char *argv[])
 	 */
 	RemovePgTempFiles();
 
+	/* Remove old auto conf temp files leftout */
+	RemoveAutoConfTmpFiles();
+
 	/*
 	 * Remember postmaster startup time
 	 */
diff -durpN postgresql/src/backend/replication/basebackup.c postgresql.2/src/backend/replication/basebackup.c
--- postgresql/src/backend/replication/basebackup.c	2013-01-17 19:52:36.445375570 +0100
+++ postgresql.2/src/backend/replication/basebackup.c	2013-01-18 21:52:23.348661080 +0100
@@ -409,7 +409,7 @@ perform_base_backup(basebackup_options *
 		 * file is required for recovery, and even that only if there happens
 		 * to be a timeline switch in the first WAL segment that contains the
 		 * checkpoint record, or if we're taking a base backup from a standby
-		 * server and the target timeline changes while the backup is taken. 
+		 * server and the target timeline changes while the backup is taken.
 		 * But they are small and highly useful for debugging purposes, so
 		 * better include them all, always.
 		 */
@@ -755,6 +755,12 @@ sendDir(char *path, int basepathlen, boo
 					strlen(PG_TEMP_FILE_PREFIX)) == 0)
 			continue;
 
+		/* skip auto conf temporary files */
+		if (strncmp(de->d_name,
+					PG_AUTOCONF_FILENAME ".",
+					sizeof(PG_AUTOCONF_FILENAME)) == 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
diff -durpN postgresql/src/backend/utils/misc/guc.c postgresql.2/src/backend/utils/misc/guc.c
--- postgresql/src/backend/utils/misc/guc.c	2013-01-17 19:52:36.450375598 +0100
+++ postgresql.2/src/backend/utils/misc/guc.c	2013-01-18 22:03:28.266006490 +0100
@@ -57,12 +57,14 @@
 #include "postmaster/postmaster.h"
 #include "postmaster/syslogger.h"
 #include "postmaster/walwriter.h"
+#include "port.h"
 #include "replication/syncrep.h"
 #include "replication/walreceiver.h"
 #include "replication/walsender.h"
 #include "storage/bufmgr.h"
 #include "storage/standby.h"
 #include "storage/fd.h"
+#include "storage/lwlock.h"
 #include "storage/proc.h"
 #include "storage/predicate.h"
 #include "tcop/tcopprot.h"
@@ -3348,6 +3350,11 @@ static void ShowAllGUCConfig(DestReceive
 static char *_ShowOption(struct config_generic * record, bool use_units);
 static bool validate_option_array_item(const char *name, const char *value,
 						   bool skipIfNoPermissions);
+static void write_auto_conf_file(int fd, const char *filename,
+						   ConfigVariable **head_p);
+static void replace_auto_config_value(ConfigVariable **head_p, ConfigVariable **tail_p,
+				 char *config_file, char *name, char *value, bool is_quoted);
+static void set_config_file(VariableSetStmt *setstmt);
 
 
 /*
@@ -5094,6 +5101,185 @@ config_enum_get_options(struct config_en
 	return retstr.data;
 }
 
+/*
+ * Validates configuration parameter and value, incase of source is default
+ * returns the default value in string format.
+ */
+struct config_generic *
+validate_conf_option(const char *name, 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;
+					}
+				}
+			}
+			break;
+		case PGC_ENUM:
+			{
+				struct config_enum *conf = (struct config_enum *) record;
+				int			newval;
+				void	   *newextra = NULL;
+
+				if (value)
+				{
+					if (!config_enum_lookup_by_name(conf, value, &newval))
+					{
+						char	   *hintmsg;
+
+						hintmsg = config_enum_get_options(conf,
+														"Available values: ",
+														  ".", ", ");
+
+						ereport(ERROR,
+								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+						 errmsg("invalid value for parameter \"%s\": \"%s\"",
+								name, value),
+								 hintmsg ? errhint("%s", _(hintmsg)) : 0));
+
+						if (hintmsg)
+							pfree(hintmsg);
+						return NULL;
+					}
+					if (!call_enum_check_hook(conf, &newval, &newextra,
+											  PGC_S_FILE, LOG))
+						return NULL;
+				}
+			}
+	}
+
+	return record;
+}
+
 
 /*
  * Sets option `name' to given value.
@@ -5897,6 +6083,335 @@ set_config_sourcefile(const char *name,
 }
 
 /*
+ * Remove auto conf temporary files left over from a prior postmaster session
+ */
+void
+RemoveAutoConfTmpFiles(void)
+{
+	char		AutoConfPath[MAXPGPATH];
+	DIR		   *config_dir;
+	struct dirent *temp_de;
+	char		rm_path[MAXPGPATH];
+
+	snprintf(AutoConfPath, sizeof(AutoConfPath), "%s/%s",
+							data_directory,
+							PG_AUTOCONF_DIR);
+
+	config_dir = AllocateDir(AutoConfPath);
+	if (config_dir == NULL)
+	{
+		/* anything except ENOENT is fishy */
+		if (errno != ENOENT)
+			elog(LOG,
+				 "could not open automatic configuration directory \"%s\": %m",
+				 AutoConfPath);
+		return;
+	}
+
+	while ((temp_de = ReadDir(config_dir, AutoConfPath)) != NULL)
+	{
+		if (strcmp(temp_de->d_name, ".") == 0 ||
+			strcmp(temp_de->d_name, "..") == 0 ||
+			strcmp(temp_de->d_name, PG_AUTOCONF_FILENAME) == 0)
+			continue;
+
+		snprintf(rm_path, sizeof(rm_path), "%s/%s",
+					AutoConfPath, temp_de->d_name);
+
+		if (strncmp(temp_de->d_name,
+					PG_AUTOCONF_FILENAME ".",
+					sizeof(PG_AUTOCONF_FILENAME)) == 0)
+			unlink(rm_path);	/* note we ignore any error */
+		else
+			elog(LOG,
+				 "unexpected file found in automatic configuration directory: \"%s\"",
+				 rm_path);
+	}
+
+	FreeDir(config_dir);
+}
+
+
+/*
+ * Write updated configuration parameter values into
+ * postgresql.auto.conf.PID file
+ */
+static void
+write_auto_conf_file(int fd, const char *filename, ConfigVariable **head_p)
+{
+	ConfigVariable *item;
+	StringInfoData buf;
+
+	initStringInfo(&buf);
+
+	for (item = *head_p; item != NULL; item = item->next)
+	{
+		appendStringInfoString(&buf, item->name);
+		appendStringInfoString(&buf, " = ");
+
+		if (true == item->is_quoted)
+		{
+			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 to \"%s\" file",
+							filename)));
+		}
+
+		resetStringInfo(&buf);
+	}
+
+	if (pg_fsync(fd) != 0)
+		ereport(ERROR,
+				(errcode_for_file_access(),
+				 errmsg("could not fsync file \"%s\": %m",
+				 			filename)));
+
+	pfree(buf.data);
+}
+
+
+/*
+ * Replace the updated configuration parameter value in
+ * postgresql.auto.conf. If the parameter is new then
+ * it's appended to the list of parameters.
+ */
+static void
+replace_auto_config_value(ConfigVariable **head_p, ConfigVariable **tail_p,
+						 char *config_file,
+						 char *name, char *value,
+						 bool is_quoted)
+{
+	ConfigVariable *item,
+			   *prev = NULL;
+
+	if (NULL != *head_p)
+	{
+		for (item = *head_p; item != NULL; item = item->next)
+		{
+			if (strcmp(item->name, name) == 0)
+			{
+				pfree(item->value);
+				if (value)
+				{
+					/* update the parameter value */
+					item->value = pstrdup(value);
+				}
+				else
+				{
+					/* delete the configuration parameter from list */
+					if (*head_p == item)
+					{
+						*head_p = item->next;
+					}
+					else
+					{
+						prev->next = item->next;
+					}
+
+					if (*tail_p == item)
+					{
+						*tail_p = prev;
+					}
+					pfree(item->name);
+					pfree(item->filename);
+					pfree(item);
+				}
+				return;
+			}
+			prev = item;
+		}
+	}
+
+	if (NULL == value)
+	{
+		return;
+	}
+
+	item = palloc(sizeof *item);
+	item->name = pstrdup(name);
+	item->value = pstrdup(value);
+	item->is_quoted = is_quoted;
+	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;
+}
+
+
+/*
+ * Persist the configuration parameter value.
+ *
+ * This function takes all previously set persistent
+ * configuration parameters and the currently set ones
+ * and write them all to the automatic configuration file.
+ *
+ * The configuration parameters are written to a temporary
+ * file then renamed to the final name. The template for the
+ * temporary file is postgresql.auto.conf.<PID>.
+ *
+ * An LWLock is used to serialize writing to the same file.
+ *
+ * In case of an error, we leave the original automatic
+ * configuration file (postgresql.auto.conf) intact.
+ * A stale temporary file may be left behind in case we crash.
+ * Such files are removed on the next server restart.
+ */
+static void
+set_config_file(VariableSetStmt *setstmt)
+{
+	char	   *name;
+	char	   *value;
+	int			Tmpfd = -1;
+	FILE	   *infile;
+	struct config_generic *record;
+	ConfigVariable *head_p = NULL;
+	ConfigVariable *tail_p = NULL;
+	char	    AutoConfFileName[MAXPGPATH];
+	char	    AutoConfTmpFileName[MAXPGPATH];
+	struct stat st;
+
+	if (!superuser())
+		ereport(ERROR,
+				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+				 (errmsg("must be superuser to execute SET/RESET PERSISTENT command"))));
+
+	if (IsTransactionBlock())
+		ereport(ERROR,
+				(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
+				 (errmsg("SET/RESET PERSISTENT command cannot run inside a transaction block"))));
+
+	/*
+	 * Validate the name and arguments [value1, value2 ... ].
+	 */
+	name = setstmt->name;
+
+	switch (setstmt->kind)
+	{
+		case VAR_SET_VALUE:
+			value = ExtractSetVariableArgs(setstmt);
+			break;
+
+		case VAR_SET_DEFAULT:
+			value = NULL;
+			break;
+
+		default:
+			return;
+	}
+
+	record = validate_conf_option(name, value);
+	if (!record)
+		ereport(ERROR,
+		(errmsg("invalid value for parameter \"%s\": \"%s\"", name, value)));
+
+	/* Frame auto conf name and auto conf sample temp file name */
+	snprintf(AutoConfFileName, sizeof(AutoConfFileName), "%s/%s/%s",
+						data_directory,
+						PG_AUTOCONF_DIR,
+						PG_AUTOCONF_FILENAME);
+	snprintf(AutoConfTmpFileName, sizeof(AutoConfTmpFileName),"%s/%s/%s.%d",
+						data_directory,
+						PG_AUTOCONF_DIR,
+						PG_AUTOCONF_FILENAME,
+						(int) getpid());
+
+	LWLockAcquire(SetPersistentLock, LW_EXCLUSIVE);
+
+	Tmpfd = open(AutoConfTmpFileName, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
+	if (Tmpfd < 0)
+		ereport(ERROR,
+				(errcode_for_file_access(),
+				 errmsg("could not create unique temporary file \"%s\": %m ",
+								 AutoConfTmpFileName),
+				 errhint("please remove the temporary files from the automatic configuration directory")));
+
+	PG_TRY();
+	{
+		if (stat(AutoConfFileName, &st) != 0)
+		{
+			int			fd;
+
+			fd = open(AutoConfFileName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
+			if (fd < 0)
+				ereport(ERROR,
+						(errcode_for_file_access(),
+						 errmsg("creating \"%s\" failed: %m",
+						 		 AutoConfFileName)));
+			close(fd);
+
+			ereport(NOTICE,
+				 (errmsg("created automatic configuration file \"%s\"",
+								 AutoConfFileName)));
+		}
+
+		/* open postgresql.auto.conf file */
+		infile = AllocateFile(AutoConfFileName, "r");
+		if (infile == NULL)
+			ereport(ERROR,
+					(errmsg("failed to open \"" PG_AUTOCONF_FILENAME "\" file")));
+
+		/* Parse the postgresql.auto.conf file */
+		ParseConfigFp(infile, AutoConfFileName, 0, LOG, &head_p, &tail_p);
+
+		FreeFile(infile);
+
+		/* replace with new value */
+		replace_auto_config_value(&head_p, &tail_p, AutoConfFileName, name,
+					  value, (record->vartype == PGC_STRING) ? true : false);
+
+		/* Write the New contents to postgresql.auto.conf.<PID> file */
+		write_auto_conf_file(Tmpfd, AutoConfTmpFileName, &head_p);
+
+		close(Tmpfd);
+		Tmpfd = -1;
+
+		if (rename(AutoConfTmpFileName, AutoConfFileName) < 0)
+			ereport(ERROR,
+					(errcode_for_file_access(),
+					 errmsg("could not rename file \"%s\" to \"%s\" : %m",
+							AutoConfTmpFileName, AutoConfFileName)));
+	}
+	PG_CATCH();
+	{
+		if (Tmpfd >= 0)
+			close(Tmpfd);
+
+		unlink(AutoConfTmpFileName);
+		PG_RE_THROW();
+	}
+	PG_END_TRY();
+
+	LWLockRelease(SetPersistentLock);
+	return;
+}
+
+
+/*
  * Set a config option to the given value.
  *
  * See also set_config_option; this is just the wrapper to be called from
@@ -6167,6 +6682,12 @@ ExecSetVariableStmt(VariableSetStmt *stm
 	switch (stmt->kind)
 	{
 		case VAR_SET_VALUE:
+			if (stmt->is_persistent)
+			{
+				set_config_file(stmt);
+				break;
+			}
+			/* FALLTHROUGH */
 		case VAR_SET_CURRENT:
 			(void) set_config_option(stmt->name,
 									 ExtractSetVariableArgs(stmt),
@@ -6246,6 +6767,12 @@ ExecSetVariableStmt(VariableSetStmt *stm
 					 stmt->name);
 			break;
 		case VAR_SET_DEFAULT:
+			if (stmt->is_persistent)
+			{
+				set_config_file(stmt);
+				break;
+			}
+			/* FALLTHROUGH */
 		case VAR_RESET:
 			(void) set_config_option(stmt->name,
 									 NULL,
diff -durpN postgresql/src/backend/utils/misc/guc-file.l postgresql.2/src/backend/utils/misc/guc-file.l
--- postgresql/src/backend/utils/misc/guc-file.l	2013-01-02 09:19:03.845521694 +0100
+++ postgresql.2/src/backend/utils/misc/guc-file.l	2013-01-18 20:36:22.891842079 +0100
@@ -41,6 +41,7 @@ enum {
 	GUC_ERROR = 100
 };
 
+static bool is_config_dir_parsed = false;
 static unsigned int ConfigFileLineno;
 static const char *GUC_flex_fatal_errmsg;
 static sigjmp_buf *GUC_flex_fatal_jmp;
@@ -137,6 +138,8 @@ ProcessConfigFile(GucContext context)
 	/* Parse the file into a list of option names and values */
 	head = tail = NULL;
 
+	is_config_dir_parsed = false;
+
 	if (!ParseConfigFile(ConfigFileName, NULL, true, 0, elevel, &head, &tail))
 	{
 		/* Syntax error(s) detected in the file, so bail out */
@@ -144,6 +147,15 @@ ProcessConfigFile(GucContext context)
 		goto cleanup_list;
 	}
 
+	if (!is_config_dir_parsed)
+	{
+		ereport(WARNING,
+				(errmsg("Default \"%s\" is not present in postgresql.conf. "
+					"Configuration parameters changed with SET PERSISTENT "
+					"command will not be effective.",
+					PG_AUTOCONF_DIR)));
+	}
+
 	/*
 	 * Mark all extant GUC variables as not present in the config file.
 	 * We need this so that we can tell below which ones have been removed
@@ -411,6 +423,8 @@ ParseConfigFile(const char *config_file,
 {
 	bool		OK = true;
 	FILE	   *fp;
+	char 	   *ConfigAutoFileName;
+	char		Filename[MAXPGPATH];
 
 	/*
 	 * Reject too-deep include nesting depth.  This is just a safety check
@@ -427,6 +441,13 @@ ParseConfigFile(const char *config_file,
 	}
 
 	config_file = AbsoluteConfigLocation(config_file,calling_file);
+
+	/* Checking for the postgresql.auto.conf file is parsed or not */
+	snprintf(Filename,sizeof(Filename),"%s/%s", PG_AUTOCONF_DIR, PG_AUTOCONF_FILENAME);
+	ConfigAutoFileName = AbsoluteConfigLocation(Filename, ConfigFileName);
+	if (depth == 1 && strcmp(ConfigAutoFileName, config_file) == 0)
+		is_config_dir_parsed = true;
+
 	fp = AllocateFile(config_file, "r");
 	if (!fp)
 	{
@@ -533,6 +554,7 @@ ParseConfigFp(FILE *fp, const char *conf
 	{
 		char	   *opt_name = NULL;
 		char	   *opt_value = NULL;
+		bool		is_string = false;
 		ConfigVariable *item;
 
 		if (token == GUC_EOL)	/* empty or comment line */
@@ -556,7 +578,10 @@ ParseConfigFp(FILE *fp, const char *conf
 			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,6 +645,7 @@ ParseConfigFp(FILE *fp, const char *conf
 			item = palloc(sizeof *item);
 			item->name = opt_name;
 			item->value = opt_value;
+			item->is_quoted = is_string;
 			item->filename = pstrdup(config_file);
 			item->sourceline = ConfigFileLineno-1;
 			item->next = NULL;
diff -durpN postgresql/src/backend/utils/misc/postgresql.conf.sample postgresql.2/src/backend/utils/misc/postgresql.conf.sample
--- postgresql/src/backend/utils/misc/postgresql.conf.sample	2013-01-17 19:52:36.451375603 +0100
+++ postgresql.2/src/backend/utils/misc/postgresql.conf.sample	2013-01-18 17:34:56.203963695 +0100
@@ -581,6 +581,13 @@
 #include_if_exists = 'exists.conf'	# include file only if it exists
 #include = 'special.conf'		# include file
 
+# This includes the default configuration directory included to support
+# SET PERSISTENT statement.
+#
+# WARNING: Any configuration parameter values specified after this line
+#           will override the values set by SET PERSISTENT statement.
+#include_dir = 'auto.conf.d'
+
 #------------------------------------------------------------------------------
 # CUSTOMIZED OPTIONS
 #------------------------------------------------------------------------------
diff -durpN postgresql/src/bin/initdb/initdb.c postgresql.2/src/bin/initdb/initdb.c
--- postgresql/src/bin/initdb/initdb.c	2013-01-05 17:34:30.777135618 +0100
+++ postgresql.2/src/bin/initdb/initdb.c	2013-01-18 22:02:05.792467941 +0100
@@ -192,7 +192,8 @@ const char *subdirs[] = {
 	"base",
 	"base/1",
 	"pg_tblspc",
-	"pg_stat_tmp"
+	"pg_stat_tmp",
+	PG_AUTOCONF_DIR
 };
 
 
@@ -1209,6 +1210,7 @@ setup_config(void)
 	char		repltok[MAXPGPATH];
 	char		path[MAXPGPATH];
 	const char *default_timezone;
+	FILE	   *autofile;
 
 	fputs(_("creating configuration files ... "), stdout);
 	fflush(stdout);
@@ -1291,11 +1293,34 @@ setup_config(void)
 		conflines = replace_token(conflines, "#log_timezone = 'GMT'", repltok);
 	}
 
+	snprintf(repltok, sizeof(repltok), "include_dir = '" PG_AUTOCONF_DIR "'");
+	conflines = replace_token(conflines, "#include_dir = 'auto.conf.d'", repltok);
+
 	snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
 
 	writefile(path, conflines);
 	chmod(path, S_IRUSR | S_IWUSR);
 
+	/* create the automatic configuration file */
+	sprintf(path, "%s/%s/%s", pg_data, PG_AUTOCONF_DIR, PG_AUTOCONF_FILENAME);
+	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);
 
 
diff -durpN postgresql/src/include/nodes/parsenodes.h postgresql.2/src/include/nodes/parsenodes.h
--- postgresql/src/include/nodes/parsenodes.h	2013-01-02 09:19:03.897522265 +0100
+++ postgresql.2/src/include/nodes/parsenodes.h	2013-01-18 17:34:56.205963709 +0100
@@ -1425,6 +1425,7 @@ typedef struct VariableSetStmt
 	char	   *name;			/* variable to be set */
 	List	   *args;			/* List of A_Const nodes */
 	bool		is_local;		/* SET LOCAL? */
+	bool		is_persistent;	/* SET PERSISTENT? */
 } VariableSetStmt;
 
 /* ----------------------
diff -durpN postgresql/src/include/parser/kwlist.h postgresql.2/src/include/parser/kwlist.h
--- postgresql/src/include/parser/kwlist.h	2013-01-02 09:19:03.900522297 +0100
+++ postgresql.2/src/include/parser/kwlist.h	2013-01-18 17:34:56.205963709 +0100
@@ -279,6 +279,7 @@ PG_KEYWORD("partial", PARTIAL, UNRESERVE
 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)
diff -durpN postgresql/src/include/pg_config_manual.h postgresql.2/src/include/pg_config_manual.h
--- postgresql/src/include/pg_config_manual.h	2013-01-02 09:19:03.902522322 +0100
+++ postgresql.2/src/include/pg_config_manual.h	2013-01-18 21:46:33.097368601 +0100
@@ -266,3 +266,10 @@
 /* #define HEAPDEBUGALL */
 /* #define ACLDEBUG */
 /* #define RTDEBUG */
+
+/*
+ * Automatic configuration directory and file name
+ * for SET PERSISTENT.
+ */
+#define PG_AUTOCONF_DIR			"auto.conf.d"
+#define PG_AUTOCONF_FILENAME		"postgresql.auto.conf"
diff -durpN postgresql/src/include/storage/lwlock.h postgresql.2/src/include/storage/lwlock.h
--- postgresql/src/include/storage/lwlock.h	2013-01-02 09:19:03.906522364 +0100
+++ postgresql.2/src/include/storage/lwlock.h	2013-01-18 17:34:56.205963709 +0100
@@ -79,6 +79,7 @@ typedef enum LWLockId
 	SerializablePredicateLockListLock,
 	OldSerXidLock,
 	SyncRepLock,
+	SetPersistentLock,
 	/* Individual lock IDs end here */
 	FirstBufMappingLock,
 	FirstLockMgrLock = FirstBufMappingLock + NUM_BUFFER_PARTITIONS,
diff -durpN postgresql/src/include/utils/guc.h postgresql.2/src/include/utils/guc.h
--- postgresql/src/include/utils/guc.h	2013-01-02 09:19:03.910522408 +0100
+++ postgresql.2/src/include/utils/guc.h	2013-01-18 20:52:37.705844449 +0100
@@ -105,6 +105,7 @@ typedef struct ConfigVariable
 {
 	char	   *name;
 	char	   *value;
+	bool		is_quoted;
 	char	   *filename;
 	int			sourceline;
 	struct ConfigVariable *next;
@@ -233,6 +234,8 @@ extern int	tcp_keepalives_count;
 /*
  * Functions exported by guc.c
  */
+extern void RemoveAutoConfTmpFiles(void);
+
 extern void SetConfigOption(const char *name, const char *value,
 				GucContext context, GucSource source);
 
diff -durpN postgresql/src/include/utils/guc_tables.h postgresql.2/src/include/utils/guc_tables.h
--- postgresql/src/include/utils/guc_tables.h	2013-01-02 09:19:03.910522408 +0100
+++ postgresql.2/src/include/utils/guc_tables.h	2013-01-18 17:34:56.206963716 +0100
@@ -260,6 +260,6 @@ extern void build_guc_variables(void);
 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, char *value);
 
 #endif   /* GUC_TABLES_H */
diff -durpN postgresql/src/test/regress/expected/persistent.out postgresql.2/src/test/regress/expected/persistent.out
--- postgresql/src/test/regress/expected/persistent.out	1970-01-01 01:00:00.000000000 +0100
+++ postgresql.2/src/test/regress/expected/persistent.out	2013-01-18 17:34:56.207963723 +0100
@@ -0,0 +1,584 @@
+-- parameter which cannot be set after connection start.
+set persistent log_connections=on;
+-- parameter can only be set at during server start.
+set persistent max_connections To 10;
+set persistent wal_level = hot_standby;
+-- parameter can set by the backend
+set persistent authentication_timeout = 10;
+set persistent vacuum_cost_delay To 200;
+ERROR:  200 is outside the valid range for parameter "vacuum_cost_delay" (0 .. 100)
+set persistent bgwriter_lru_multiplier = 3.2;
+set persistent full_page_writes = off;
+set persistent synchronous_commit To off;
+set persistent synchronous_standby_names = 'standby1, standby2';
+set persistent seq_page_cost = 0.9;
+set persistent autovacuum_naptime To 30;
+set persistent search_path = 'public';
+set persistent default_tablespace = '';
+set persistent checkpoint_timeout = 1;
+ERROR:  1 is outside the valid range for parameter "checkpoint_timeout" (30 .. 3600)
+set persistent checkpoint_timeout = 3700;
+ERROR:  3700 is outside the valid range for parameter "checkpoint_timeout" (30 .. 3600)
+set persistent checkpoint_timeout = 90;
+set persistent restart_after_crash TO on;
+show log_connections;
+ log_connections 
+-----------------
+ off
+(1 row)
+
+show max_connections;
+ max_connections 
+-----------------
+ 100
+(1 row)
+
+show wal_level;
+ wal_level 
+-----------
+ minimal
+(1 row)
+
+show authentication_timeout;
+ authentication_timeout 
+------------------------
+ 1min
+(1 row)
+
+show vacuum_cost_delay;
+ vacuum_cost_delay 
+-------------------
+ 0
+(1 row)
+
+show bgwriter_lru_multiplier;
+ bgwriter_lru_multiplier 
+-------------------------
+ 2
+(1 row)
+
+show full_page_writes;
+ full_page_writes 
+------------------
+ on
+(1 row)
+
+show synchronous_commit;
+ synchronous_commit 
+--------------------
+ on
+(1 row)
+
+show synchronous_standby_names;
+ synchronous_standby_names 
+---------------------------
+ 
+(1 row)
+
+show seq_page_cost;
+ seq_page_cost 
+---------------
+ 1
+(1 row)
+
+show autovacuum_naptime;
+ autovacuum_naptime 
+--------------------
+ 1min
+(1 row)
+
+show search_path;
+  search_path   
+----------------
+ "$user",public
+(1 row)
+
+show default_tablespace;
+ default_tablespace 
+--------------------
+ 
+(1 row)
+
+show checkpoint_timeout;
+ checkpoint_timeout 
+--------------------
+ 5min
+(1 row)
+
+show restart_after_crash;
+ restart_after_crash 
+---------------------
+ on
+(1 row)
+
+-- reload the new configurations.
+select pg_reload_conf();
+ pg_reload_conf 
+----------------
+ t
+(1 row)
+
+select pg_sleep(1);
+ pg_sleep 
+----------
+ 
+(1 row)
+
+show log_connections;
+ log_connections 
+-----------------
+ off
+(1 row)
+
+show max_connections;
+ max_connections 
+-----------------
+ 100
+(1 row)
+
+show wal_level;
+ wal_level 
+-----------
+ minimal
+(1 row)
+
+show authentication_timeout;
+ authentication_timeout 
+------------------------
+ 10s
+(1 row)
+
+show vacuum_cost_delay;
+ vacuum_cost_delay 
+-------------------
+ 0
+(1 row)
+
+show bgwriter_lru_multiplier;
+ bgwriter_lru_multiplier 
+-------------------------
+ 3.2
+(1 row)
+
+show full_page_writes;
+ full_page_writes 
+------------------
+ off
+(1 row)
+
+show synchronous_commit;
+ synchronous_commit 
+--------------------
+ off
+(1 row)
+
+show synchronous_standby_names;
+ synchronous_standby_names 
+---------------------------
+ standby1, standby2
+(1 row)
+
+show seq_page_cost;
+ seq_page_cost 
+---------------
+ 0.9
+(1 row)
+
+show autovacuum_naptime;
+ autovacuum_naptime 
+--------------------
+ 30s
+(1 row)
+
+show search_path;
+ search_path 
+-------------
+ public
+(1 row)
+
+show default_tablespace;
+ default_tablespace 
+--------------------
+ 
+(1 row)
+
+show checkpoint_timeout;
+ checkpoint_timeout 
+--------------------
+ 90s
+(1 row)
+
+show restart_after_crash;
+ restart_after_crash 
+---------------------
+ on
+(1 row)
+
+-- reconnect to see the new configurations
+\c
+select name, setting from pg_settings where name = 'log_connections';
+      name       | setting 
+-----------------+---------
+ log_connections | on
+(1 row)
+
+select name, setting from pg_settings where name = 'max_connections';
+      name       | setting 
+-----------------+---------
+ max_connections | 100
+(1 row)
+
+select name, setting from pg_settings where name = 'wal_level';
+   name    | setting 
+-----------+---------
+ wal_level | minimal
+(1 row)
+
+select name, setting from pg_settings where name = 'authentication_timeout';
+          name          | setting 
+------------------------+---------
+ authentication_timeout | 10
+(1 row)
+
+select name, setting from pg_settings where name = 'vacuum_cost_delay';
+       name        | setting 
+-------------------+---------
+ vacuum_cost_delay | 0
+(1 row)
+
+select name, setting from pg_settings where name = 'bgwriter_lru_multiplier';
+          name           | setting 
+-------------------------+---------
+ bgwriter_lru_multiplier | 3.2
+(1 row)
+
+select name, setting from pg_settings where name = 'full_page_writes';
+       name       | setting 
+------------------+---------
+ full_page_writes | off
+(1 row)
+
+select name, setting from pg_settings where name = 'synchronous_commit';
+        name        | setting 
+--------------------+---------
+ synchronous_commit | off
+(1 row)
+
+select name, setting from pg_settings where name = 'synchronous_standby_names';
+           name            |      setting       
+---------------------------+--------------------
+ synchronous_standby_names | standby1, standby2
+(1 row)
+
+select name, setting from pg_settings where name = 'seq_page_cost';
+     name      | setting 
+---------------+---------
+ seq_page_cost | 0.9
+(1 row)
+
+select name, setting from pg_settings where name = 'autovacuum_naptime';
+        name        | setting 
+--------------------+---------
+ autovacuum_naptime | 30
+(1 row)
+
+select name, setting from pg_settings where name = 'search_path';
+    name     | setting 
+-------------+---------
+ search_path | public
+(1 row)
+
+select name, setting from pg_settings where name = 'default_tablespace';
+        name        | setting 
+--------------------+---------
+ default_tablespace | 
+(1 row)
+
+select name, setting from pg_settings where name = 'checkpoint_timeout';
+        name        | setting 
+--------------------+---------
+ checkpoint_timeout | 90
+(1 row)
+
+select name, setting from pg_settings where name = 'restart_after_crash';
+        name         | setting 
+---------------------+---------
+ restart_after_crash | on
+(1 row)
+
+-- Reset the some of the parameters which are set in above
+set persistent log_connections = default;
+set persistent max_connections To default;
+set persistent authentication_timeout To default;
+set persistent synchronous_commit = default;
+set persistent restart_after_crash To default;
+-- reload the new configurations.
+select pg_reload_conf();
+ pg_reload_conf 
+----------------
+ t
+(1 row)
+
+select pg_sleep(1);
+ pg_sleep 
+----------
+ 
+(1 row)
+
+select name, setting from pg_settings where name = 'log_connections';
+      name       | setting 
+-----------------+---------
+ log_connections | on
+(1 row)
+
+select name, setting from pg_settings where name = 'max_connections';
+      name       | setting 
+-----------------+---------
+ max_connections | 100
+(1 row)
+
+select name, setting from pg_settings where name = 'authentication_timeout';
+          name          | setting 
+------------------------+---------
+ authentication_timeout | 60
+(1 row)
+
+select name, setting from pg_settings where name = 'seq_page_cost';
+     name      | setting 
+---------------+---------
+ seq_page_cost | 0.9
+(1 row)
+
+select name, setting from pg_settings where name = 'restart_after_crash';
+        name         | setting 
+---------------------+---------
+ restart_after_crash | on
+(1 row)
+
+-- reconnect to see the new configurations
+\c
+show log_connections;
+ log_connections 
+-----------------
+ off
+(1 row)
+
+show max_connections;
+ max_connections 
+-----------------
+ 100
+(1 row)
+
+show authentication_timeout;
+ authentication_timeout 
+------------------------
+ 1min
+(1 row)
+
+show seq_page_cost;
+ seq_page_cost 
+---------------
+ 0.9
+(1 row)
+
+show restart_after_crash;
+ restart_after_crash 
+---------------------
+ on
+(1 row)
+
+-- set the parameters again which are reset above.
+set persistent log_connections To yes;
+set persistent max_connections = 50;
+set persistent authentication_timeout = 20;
+set persistent synchronous_commit To off;
+set persistent restart_after_crash To yes;
+-- reload the new configurations.
+select pg_reload_conf();
+ pg_reload_conf 
+----------------
+ t
+(1 row)
+
+select pg_sleep(1);
+ pg_sleep 
+----------
+ 
+(1 row)
+
+show log_connections;
+ log_connections 
+-----------------
+ off
+(1 row)
+
+show max_connections;
+ max_connections 
+-----------------
+ 100
+(1 row)
+
+show authentication_timeout;
+ authentication_timeout 
+------------------------
+ 20s
+(1 row)
+
+show seq_page_cost;
+ seq_page_cost 
+---------------
+ 0.9
+(1 row)
+
+show restart_after_crash;
+ restart_after_crash 
+---------------------
+ on
+(1 row)
+
+-- reconnect to see the new configurations
+\c
+show log_connections;
+ log_connections 
+-----------------
+ on
+(1 row)
+
+show max_connections;
+ max_connections 
+-----------------
+ 100
+(1 row)
+
+show authentication_timeout;
+ authentication_timeout 
+------------------------
+ 20s
+(1 row)
+
+show seq_page_cost;
+ seq_page_cost 
+---------------
+ 0.9
+(1 row)
+
+show restart_after_crash;
+ restart_after_crash 
+---------------------
+ on
+(1 row)
+
+-- set a configuration param inside a function
+create or replace function persistent_func() returns integer as
+$$
+begin
+set persistent enable_hashagg=off;
+return 1;
+end;
+$$ Language plpgsql;
+select persistent_func();
+ persistent_func 
+-----------------
+               1
+(1 row)
+
+show enable_hashagg;
+ enable_hashagg 
+----------------
+ on
+(1 row)
+
+select pg_reload_conf();
+ pg_reload_conf 
+----------------
+ t
+(1 row)
+
+select pg_sleep(1);
+ pg_sleep 
+----------
+ 
+(1 row)
+
+show enable_hashagg;
+ enable_hashagg 
+----------------
+ off
+(1 row)
+
+create or replace function persistent_func() returns integer as
+$$
+begin
+set persistent enable_hashagg=default;
+return 1;
+end;
+$$ Language plpgsql;
+select persistent_func();
+ persistent_func 
+-----------------
+               1
+(1 row)
+
+select pg_reload_conf();
+ pg_reload_conf 
+----------------
+ t
+(1 row)
+
+select pg_sleep(1);
+ pg_sleep 
+----------
+ 
+(1 row)
+
+show enable_hashagg;
+ enable_hashagg 
+----------------
+ on
+(1 row)
+
+Drop function persistent_func();
+-- Reset all parameters which are set at above.
+set persistent log_connections To default;
+set persistent max_connections = default;
+set persistent wal_level To default;
+set persistent authentication_timeout To default;
+set persistent vacuum_cost_delay = default;
+set persistent bgwriter_lru_multiplier To default;
+set persistent full_page_writes To default;
+set persistent synchronous_commit = default;
+set persistent synchronous_standby_names To default;
+set persistent seq_page_cost To default;
+set persistent autovacuum_naptime = default;
+set persistent search_path To default;
+set persistent default_tablespace To default;
+set persistent checkpoint_timeout To default;
+set persistent restart_after_crash = default;
+select pg_reload_conf();
+ pg_reload_conf 
+----------------
+ t
+(1 row)
+
+select pg_sleep(1);
+ pg_sleep 
+----------
+ 
+(1 row)
+
+-- Normal user tries to set
+create user test password 'test';
+SET SESSION AUTHORIZATION test;
+set persistent enable_seqscan=off;
+ERROR:  must be superuser to execute SET/RESET PERSISTENT command
+\c -
+drop user test;
+-- In a transaction block tries to set
+start transaction;
+set persistent enable_hashagg=off;
+ERROR:  SET/RESET PERSISTENT command cannot run inside a transaction block
+commit;
+start transaction;
+set persistent enable_hashagg=default;
+ERROR:  SET/RESET PERSISTENT command cannot run inside a transaction block
+commit;
diff -durpN postgresql/src/test/regress/parallel_schedule postgresql.2/src/test/regress/parallel_schedule
--- postgresql/src/test/regress/parallel_schedule	2012-12-10 11:41:36.630597674 +0100
+++ postgresql.2/src/test/regress/parallel_schedule	2013-01-18 17:34:56.207963723 +0100
@@ -108,4 +108,7 @@ test: select_views portals_p2 foreign_ke
 test: plancache limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml
 
 # run stats by itself because its delay may be insufficient under heavy load
-test: stats
+test: stats 
+
+# run persistent by itself because it modifies the configuration parameters
+test: persistent
diff -durpN postgresql/src/test/regress/serial_schedule postgresql.2/src/test/regress/serial_schedule
--- postgresql/src/test/regress/serial_schedule	2012-12-10 11:41:36.630597674 +0100
+++ postgresql.2/src/test/regress/serial_schedule	2013-01-18 17:34:56.207963723 +0100
@@ -135,3 +135,4 @@ test: largeobject
 test: with
 test: xml
 test: stats
+test: persistent
diff -durpN postgresql/src/test/regress/sql/persistent.sql postgresql.2/src/test/regress/sql/persistent.sql
--- postgresql/src/test/regress/sql/persistent.sql	1970-01-01 01:00:00.000000000 +0100
+++ postgresql.2/src/test/regress/sql/persistent.sql	2013-01-18 17:34:56.207963723 +0100
@@ -0,0 +1,215 @@
+-- parameter which cannot be set after connection start.
+set persistent log_connections=on;
+
+-- parameter can only be set at during server start.
+set persistent max_connections To 10;
+set persistent wal_level = hot_standby;
+
+-- parameter can set by the backend
+set persistent authentication_timeout = 10;
+set persistent vacuum_cost_delay To 200;
+set persistent bgwriter_lru_multiplier = 3.2;
+set persistent full_page_writes = off;
+set persistent synchronous_commit To off;
+set persistent synchronous_standby_names = 'standby1, standby2';
+set persistent seq_page_cost = 0.9;
+set persistent autovacuum_naptime To 30;
+set persistent search_path = 'public';
+set persistent default_tablespace = '';
+set persistent checkpoint_timeout = 1;
+set persistent checkpoint_timeout = 3700;
+set persistent checkpoint_timeout = 90;
+set persistent restart_after_crash TO on;
+
+
+show log_connections;
+
+show max_connections;
+show wal_level;
+
+show authentication_timeout;
+show vacuum_cost_delay;
+show bgwriter_lru_multiplier;
+show full_page_writes;
+show synchronous_commit;
+show synchronous_standby_names;
+show seq_page_cost;
+show autovacuum_naptime;
+show search_path;
+show default_tablespace;
+show checkpoint_timeout;
+show restart_after_crash;
+
+-- reload the new configurations.
+select pg_reload_conf();
+select pg_sleep(1);
+
+show log_connections;
+
+show max_connections;
+show wal_level;
+
+show authentication_timeout;
+show vacuum_cost_delay;
+show bgwriter_lru_multiplier;
+show full_page_writes;
+show synchronous_commit;
+show synchronous_standby_names;
+show seq_page_cost;
+show autovacuum_naptime;
+show search_path;
+show default_tablespace;
+show checkpoint_timeout;
+show restart_after_crash;
+
+
+-- reconnect to see the new configurations
+\c
+
+select name, setting from pg_settings where name = 'log_connections';
+
+select name, setting from pg_settings where name = 'max_connections';
+select name, setting from pg_settings where name = 'wal_level';
+
+select name, setting from pg_settings where name = 'authentication_timeout';
+select name, setting from pg_settings where name = 'vacuum_cost_delay';
+select name, setting from pg_settings where name = 'bgwriter_lru_multiplier';
+select name, setting from pg_settings where name = 'full_page_writes';
+select name, setting from pg_settings where name = 'synchronous_commit';
+select name, setting from pg_settings where name = 'synchronous_standby_names';
+select name, setting from pg_settings where name = 'seq_page_cost';
+select name, setting from pg_settings where name = 'autovacuum_naptime';
+select name, setting from pg_settings where name = 'search_path';
+select name, setting from pg_settings where name = 'default_tablespace';
+select name, setting from pg_settings where name = 'checkpoint_timeout';
+select name, setting from pg_settings where name = 'restart_after_crash';
+
+-- Reset the some of the parameters which are set in above
+set persistent log_connections = default;
+
+set persistent max_connections To default;
+
+set persistent authentication_timeout To default;
+set persistent synchronous_commit = default;
+set persistent restart_after_crash To default;
+
+-- reload the new configurations.
+select pg_reload_conf();
+select pg_sleep(1);
+
+select name, setting from pg_settings where name = 'log_connections';
+select name, setting from pg_settings where name = 'max_connections';
+select name, setting from pg_settings where name = 'authentication_timeout';
+select name, setting from pg_settings where name = 'seq_page_cost';
+select name, setting from pg_settings where name = 'restart_after_crash';
+
+-- reconnect to see the new configurations
+\c
+
+show log_connections;
+show max_connections;
+show authentication_timeout;
+show seq_page_cost;
+show restart_after_crash;
+
+-- set the parameters again which are reset above.
+set persistent log_connections To yes;
+
+set persistent max_connections = 50;
+
+set persistent authentication_timeout = 20;
+set persistent synchronous_commit To off;
+set persistent restart_after_crash To yes;
+
+-- reload the new configurations.
+select pg_reload_conf();
+select pg_sleep(1);
+
+show log_connections;
+show max_connections;
+show authentication_timeout;
+show seq_page_cost;
+show restart_after_crash;
+
+-- reconnect to see the new configurations
+\c
+show log_connections;
+show max_connections;
+show authentication_timeout;
+show seq_page_cost;
+show restart_after_crash;
+
+-- set a configuration param inside a function
+create or replace function persistent_func() returns integer as
+$$
+begin
+set persistent enable_hashagg=off;
+return 1;
+end;
+$$ Language plpgsql;
+
+select persistent_func();
+
+show enable_hashagg;
+
+select pg_reload_conf();
+select pg_sleep(1);
+
+show enable_hashagg;
+
+create or replace function persistent_func() returns integer as
+$$
+begin
+set persistent enable_hashagg=default;
+return 1;
+end;
+$$ Language plpgsql;
+
+select persistent_func();
+
+select pg_reload_conf();
+select pg_sleep(1);
+
+show enable_hashagg;
+
+Drop function persistent_func();
+
+-- Reset all parameters which are set at above.
+set persistent log_connections To default;
+
+set persistent max_connections = default;
+set persistent wal_level To default;
+
+set persistent authentication_timeout To default;
+set persistent vacuum_cost_delay = default;
+set persistent bgwriter_lru_multiplier To default;
+set persistent full_page_writes To default;
+set persistent synchronous_commit = default;
+set persistent synchronous_standby_names To default;
+set persistent seq_page_cost To default;
+set persistent autovacuum_naptime = default;
+set persistent search_path To default;
+set persistent default_tablespace To default;
+set persistent checkpoint_timeout To default;
+set persistent restart_after_crash = default;
+
+select pg_reload_conf();
+select pg_sleep(1);
+
+
+-- Normal user tries to set
+create user test password 'test';
+SET SESSION AUTHORIZATION test;
+set persistent enable_seqscan=off;
+\c -
+drop user test;
+
+-- In a transaction block tries to set
+start transaction;
+set persistent enable_hashagg=off;
+commit;
+
+start transaction;
+set persistent enable_hashagg=default;
+commit;
+
