diff --git a/src/backend/catalog/pg_db_role_setting.c b/src/backend/catalog/pg_db_role_setting.c
index cf14ea1..8df4ac5 100644
--- a/src/backend/catalog/pg_db_role_setting.c
+++ b/src/backend/catalog/pg_db_role_setting.c
@@ -21,18 +21,18 @@
 #include "utils/tqual.h"
 
 void
-AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
+AlterSetting(Oid databaseid, Oid roleid, List *setstmt, int action)
 {
-	char	   *valuestr;
 	HeapTuple	tuple;
 	Relation	rel;
 	ScanKeyData scankey[2];
 	SysScanDesc scan;
-
-	valuestr = ExtractSetVariableArgs(setstmt);
+	ListCell   *l;
+	Datum		datum;
+	bool		isnull;
+	ArrayType	*a = NULL;
 
 	/* Get the old tuple, if any. */
-
 	rel = heap_open(DbRoleSettingRelationId, RowExclusiveLock);
 	ScanKeyInit(&scankey[0],
 				Anum_pg_db_role_setting_setdatabase,
@@ -46,6 +46,13 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
 							  NULL, 2, scankey);
 	tuple = systable_getnext(scan);
 
+	if (HeapTupleIsValid(tuple))
+	{
+		datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
+							 RelationGetDescr(rel), &isnull);
+		a = isnull ? NULL :DatumGetArrayTypeP(datum);
+	}
+
 	/*
 	 * There are three cases:
 	 *
@@ -58,72 +65,52 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
 	 * - otherwise, insert a new pg_db_role_setting tuple, but only if the
 	 * command is not RESET
 	 */
-	if (setstmt->kind == VAR_RESET_ALL)
+	foreach(l, setstmt)
 	{
-		if (HeapTupleIsValid(tuple))
-		{
-			ArrayType  *new = NULL;
-			Datum		datum;
-			bool		isnull;
+		VariableSetStmt *stmt = (VariableSetStmt *) lfirst(l);
+		char   *valuestr = NULL;
 
-			datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
-								 RelationGetDescr(rel), &isnull);
+		/* Set kind of variable set by action */
+		if (action == +1)
+			stmt->kind = VAR_SET_VALUE; /* +1 = set variable */
+		else if (action == -1)
+			stmt->kind = VAR_RESET; /* -1 = reset variable */
 
-			if (!isnull)
-				new = GUCArrayReset(DatumGetArrayTypeP(datum));
-
-			if (new)
-			{
-				Datum		repl_val[Natts_pg_db_role_setting];
-				bool		repl_null[Natts_pg_db_role_setting];
-				bool		repl_repl[Natts_pg_db_role_setting];
-				HeapTuple	newtuple;
-
-				memset(repl_repl, false, sizeof(repl_repl));
-
-				repl_val[Anum_pg_db_role_setting_setconfig - 1] =
-					PointerGetDatum(new);
-				repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
-				repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;
-
-				newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
-											 repl_val, repl_null, repl_repl);
-				simple_heap_update(rel, &tuple->t_self, newtuple);
+		/* Extract old value of setconfig */
+		valuestr = ExtractSetVariableArgs(stmt);
 
-				/* Update indexes */
-				CatalogUpdateIndexes(rel, newtuple);
-			}
+		if (stmt->kind == VAR_RESET_ALL)
+		{
+			if (HeapTupleIsValid(tuple) && !isnull)
+				a = GUCArrayReset(a);
+			break;
+		}
+		else if (HeapTupleIsValid(tuple))
+		{
+			/* Update (valuestr is NULL in RESET cases) */
+			if (valuestr)
+				a = GUCArrayAdd(a, stmt->name, valuestr);
 			else
-				simple_heap_delete(rel, &tuple->t_self);
+				a = GUCArrayDelete(a, stmt->name);
 		}
+		else if (valuestr)
+			a = GUCArrayAdd(a, stmt->name, valuestr);
 	}
-	else if (HeapTupleIsValid(tuple))
-	{
-		Datum		repl_val[Natts_pg_db_role_setting];
-		bool		repl_null[Natts_pg_db_role_setting];
-		bool		repl_repl[Natts_pg_db_role_setting];
-		HeapTuple	newtuple;
-		Datum		datum;
-		bool		isnull;
-		ArrayType  *a;
-
-		memset(repl_repl, false, sizeof(repl_repl));
-		repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
-		repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;
-
-		/* Extract old value of setconfig */
-		datum = heap_getattr(tuple, Anum_pg_db_role_setting_setconfig,
-							 RelationGetDescr(rel), &isnull);
-		a = isnull ? NULL : DatumGetArrayTypeP(datum);
-
-		/* Update (valuestr is NULL in RESET cases) */
-		if (valuestr)
-			a = GUCArrayAdd(a, setstmt->name, valuestr);
-		else
-			a = GUCArrayDelete(a, setstmt->name);
 
+	/* Update system catalog */
+	if (HeapTupleIsValid(tuple))
+	{
+		/* Update or delete tuple */
 		if (a)
 		{
+			Datum		repl_val[Natts_pg_db_role_setting];
+			bool		repl_null[Natts_pg_db_role_setting];
+			bool		repl_repl[Natts_pg_db_role_setting];
+			HeapTuple	newtuple;
+
+			memset(repl_repl, false, sizeof(repl_repl));
+			repl_repl[Anum_pg_db_role_setting_setconfig - 1] = true;
+			repl_null[Anum_pg_db_role_setting_setconfig - 1] = false;
 			repl_val[Anum_pg_db_role_setting_setconfig - 1] =
 				PointerGetDatum(a);
 
@@ -137,17 +124,12 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
 		else
 			simple_heap_delete(rel, &tuple->t_self);
 	}
-	else if (valuestr)
+	else if (a)
 	{
 		/* non-null valuestr means it's not RESET, so insert a new tuple */
-		HeapTuple	newtuple;
 		Datum		values[Natts_pg_db_role_setting];
 		bool		nulls[Natts_pg_db_role_setting];
-		ArrayType  *a;
-
-		memset(nulls, false, sizeof(nulls));
-
-		a = GUCArrayAdd(NULL, setstmt->name, valuestr);
+		HeapTuple	newtuple;
 
 		values[Anum_pg_db_role_setting_setdatabase - 1] =
 			ObjectIdGetDatum(databaseid);
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 6cbe65e..e3c45d4 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -1553,7 +1553,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
 		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
 					   stmt->dbname);
 
-	AlterSetting(datid, InvalidOid, stmt->setstmt);
+	AlterSetting(datid, InvalidOid, list_make1(stmt->setstmt), stmt->action);
 
 	UnlockSharedObject(DatabaseRelationId, datid, 0, AccessShareLock);
 
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 2961ccb..7726182 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -854,6 +854,19 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
 	HeapTuple	roletuple;
 	Oid			databaseid = InvalidOid;
 	Oid			roleid = InvalidOid;
+	ListCell	*l;
+
+	/* Syntax check for case where RESET multiple parameters */
+	if (stmt->action == -1)
+	{
+		foreach(l, stmt->setstmt)
+		{
+			if (((VariableSetStmt *) lfirst(l))->args != NULL)
+				ereport(ERROR,
+						(errcode(ERRCODE_SYNTAX_ERROR),
+						 errmsg("RESET must not include values for parameteres.")));
+		}
+	}
 
 	if (stmt->role)
 	{
@@ -916,7 +929,7 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
 					 errmsg("must be superuser to alter settings globally")));
 	}
 
-	AlterSetting(databaseid, roleid, stmt->setstmt);
+	AlterSetting(databaseid, roleid, stmt->setstmt, stmt->action);
 
 	return roleid;
 }
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 223ef17..4ebb319 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -346,6 +346,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 				OptTableElementList TableElementList OptInherit definition
 				OptTypedTableElementList TypedTableElementList
 				reloptions opt_reloptions
+				useroptions useroption_list
 				OptWith distinct_clause opt_all_clause opt_definition func_args func_args_list
 				func_args_with_defaults func_args_with_defaults_list
 				aggr_args aggr_args_list
@@ -459,6 +460,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <range>	relation_expr_opt_alias
 %type <node>	tablesample_clause opt_repeatable_clause
 %type <target>	target_el single_set_clause set_target insert_column_item
+%type <defelt>	useroption_elem;
 
 %type <str>		generic_option_name
 %type <node>	generic_option_arg
@@ -1074,7 +1076,26 @@ AlterRoleSetStmt:
 					AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
 					n->role = $3;
 					n->database = $4;
-					n->setstmt = $5;
+					n->setstmt = list_make1($5);
+					n->action = 0;
+					$$ = (Node *)n;
+				}
+			| ALTER ROLE RoleSpec opt_in_database SET useroptions
+				{
+					AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
+					n->role = $3;
+					n->database = NULL;
+					n->setstmt = $6;
+					n->action = +1;
+					$$ = (Node *)n;
+				}
+			| ALTER ROLE RoleSpec opt_in_database RESET useroptions
+				{
+					AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
+					n->role = $3;
+					n->database = NULL;
+					n->setstmt = $6;
+					n->action = -1;
 					$$ = (Node *)n;
 				}
 			| ALTER ROLE ALL opt_in_database SetResetClause
@@ -1082,7 +1103,8 @@ AlterRoleSetStmt:
 					AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
 					n->role = NULL;
 					n->database = $4;
-					n->setstmt = $5;
+					n->setstmt = list_make1($5);
+					n->action = 0;
 					$$ = (Node *)n;
 				}
 		;
@@ -1105,19 +1127,63 @@ AlterUserStmt:
 				 }
 		;
 
-
 AlterUserSetStmt:
 			ALTER USER RoleSpec SetResetClause
 				{
 					AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
 					n->role = $3;
 					n->database = NULL;
-					n->setstmt = $4;
+					n->setstmt = list_make1($4);
+					n->action = 0;
 					$$ = (Node *)n;
 				}
-			;
+			| ALTER USER RoleSpec SET useroptions
+				{
+					AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
+					n->role = $3;
+					n->database = NULL;
+					n->setstmt = $5;
+					n->action = +1;
+					$$ = (Node *)n;
+				}
+			| ALTER USER RoleSpec RESET useroptions
+				{
+					AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
+					n->role = $3;
+					n->database = NULL;
+					n->setstmt = $5;
+					n->action=  -1;
+					$$ = (Node *)n;
+				}
+		;
+
+useroptions:
+			'(' useroption_list ')'				{ $$ = $2; }
+		;
 
+useroption_list:
+			useroption_elem							{ $$ = list_make1($1); }
+			| useroption_list ',' useroption_elem	{ $$ = lappend($1, $3); }
+		;
 
+useroption_elem:
+			var_name '=' var_value
+				{
+					VariableSetStmt *n = makeNode(VariableSetStmt);
+					n->kind = VAR_SET_VALUE;
+					n->name = $1;
+					n->args = list_make1($3);
+					$$ = (void *)n;
+				}
+			| var_name
+				{
+					VariableSetStmt *n = makeNode(VariableSetStmt);
+					n->kind = VAR_RESET;
+					n->name = $1;
+					n->args = NULL;
+					$$ = (void *)n;
+				}
+		;
 /*****************************************************************************
  *
  * Drop a postgresql DBMS role
@@ -8923,7 +8989,8 @@ AlterDatabaseSetStmt:
 				{
 					AlterDatabaseSetStmt *n = makeNode(AlterDatabaseSetStmt);
 					n->dbname = $3;
-					n->setstmt = $4;
+					n->setstmt = list_make1($4);
+					n->action = 0;
 					$$ = (Node *)n;
 				}
 		;
diff --git a/src/include/catalog/pg_db_role_setting.h b/src/include/catalog/pg_db_role_setting.h
index 9717569..aaf742b 100644
--- a/src/include/catalog/pg_db_role_setting.h
+++ b/src/include/catalog/pg_db_role_setting.h
@@ -61,7 +61,7 @@ typedef FormData_pg_db_role_setting *Form_pg_db_role_setting;
 /*
  * prototypes for functions in pg_db_role_setting.h
  */
-extern void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt);
+extern void AlterSetting(Oid databaseid, Oid roleid, List *setstmt, int action);
 extern void DropSetting(Oid databaseid, Oid roleid);
 extern void ApplySetting(Snapshot snapshot, Oid databaseid, Oid roleid,
 			 Relation relsetting, GucSource source);
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index abd4dd1..09c7067 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2173,7 +2173,8 @@ typedef struct AlterRoleSetStmt
 	NodeTag		type;
 	Node	   *role;			/* role */
 	char	   *database;		/* database name, or NULL */
-	VariableSetStmt *setstmt;	/* SET or RESET subcommand */
+	List	   *setstmt;		/* list of VariableSetStmt */
+	int			action;			/* +1 = set, -1 = reset, 0 = follows each element */
 } AlterRoleSetStmt;
 
 typedef struct DropRoleStmt
@@ -2743,7 +2744,8 @@ typedef struct AlterDatabaseSetStmt
 {
 	NodeTag		type;
 	char	   *dbname;			/* database name */
-	VariableSetStmt *setstmt;	/* SET or RESET subcommand */
+	List	   *setstmt;	/* list of VariableSetStmt */
+	int			action;		/* +1 = set, -1 = reset, 0 = follows each element */
 } AlterDatabaseSetStmt;
 
 /* ----------------------
diff --git a/src/test/regress/expected/rolenames.out b/src/test/regress/expected/rolenames.out
index 8f88c02..adf2b0a 100644
--- a/src/test/regress/expected/rolenames.out
+++ b/src/test/regress/expected/rolenames.out
@@ -324,31 +324,31 @@ SELECT * FROM chksetconfig();
 (0 rows)
 
 ALTER ROLE CURRENT_USER SET application_name to 'FOO';
-ALTER ROLE SESSION_USER SET application_name to 'BAR';
+ALTER ROLE SESSION_USER SET (application_name = 'BAR', log_min_duration_statement = 100);
 ALTER ROLE "current_user" SET application_name to 'FOOFOO';
 ALTER ROLE "Public" SET application_name to 'BARBAR';
 ALTER ROLE ALL SET application_name to 'SLAP';
 SELECT * FROM chksetconfig();
- db  |     role     |  rolkeyword  |         setconfig         
------+--------------+--------------+---------------------------
+ db  |     role     |  rolkeyword  |                       setconfig                       
+-----+--------------+--------------+-------------------------------------------------------
  ALL | Public       | -            | {application_name=BARBAR}
  ALL | current_user | -            | {application_name=FOOFOO}
- ALL | testrol1     | session_user | {application_name=BAR}
+ ALL | testrol1     | session_user | {application_name=BAR,log_min_duration_statement=100}
  ALL | testrol2     | current_user | {application_name=FOO}
 (4 rows)
 
 ALTER ROLE testrol1 SET application_name to 'SLAM';
 SELECT * FROM chksetconfig();
- db  |     role     |  rolkeyword  |         setconfig         
------+--------------+--------------+---------------------------
+ db  |     role     |  rolkeyword  |                       setconfig                        
+-----+--------------+--------------+--------------------------------------------------------
  ALL | Public       | -            | {application_name=BARBAR}
  ALL | current_user | -            | {application_name=FOOFOO}
- ALL | testrol1     | session_user | {application_name=SLAM}
+ ALL | testrol1     | session_user | {application_name=SLAM,log_min_duration_statement=100}
  ALL | testrol2     | current_user | {application_name=FOO}
 (4 rows)
 
 ALTER ROLE CURRENT_USER RESET application_name;
-ALTER ROLE SESSION_USER RESET application_name;
+ALTER ROLE SESSION_USER RESET (application_name, log_min_duration_statement, log_duration);
 ALTER ROLE "current_user" RESET application_name;
 ALTER ROLE "Public" RESET application_name;
 ALTER ROLE ALL RESET application_name;
@@ -376,7 +376,7 @@ SELECT * FROM chksetconfig();
 (0 rows)
 
 ALTER USER CURRENT_USER SET application_name to 'FOO';
-ALTER USER SESSION_USER SET application_name to 'BAR';
+ALTER USER SESSION_USER SET (application_name = 'BAR', log_min_duration_statement = 100);
 ALTER USER "current_user" SET application_name to 'FOOFOO';
 ALTER USER "Public" SET application_name to 'BARBAR';
 ALTER USER ALL SET application_name to 'SLAP';
@@ -384,26 +384,26 @@ ERROR:  syntax error at or near "ALL"
 LINE 1: ALTER USER ALL SET application_name to 'SLAP';
                    ^
 SELECT * FROM chksetconfig();
- db  |     role     |  rolkeyword  |         setconfig         
------+--------------+--------------+---------------------------
+ db  |     role     |  rolkeyword  |                       setconfig                       
+-----+--------------+--------------+-------------------------------------------------------
  ALL | Public       | -            | {application_name=BARBAR}
  ALL | current_user | -            | {application_name=FOOFOO}
- ALL | testrol1     | session_user | {application_name=BAR}
+ ALL | testrol1     | session_user | {application_name=BAR,log_min_duration_statement=100}
  ALL | testrol2     | current_user | {application_name=FOO}
 (4 rows)
 
 ALTER USER testrol1 SET application_name to 'SLAM';
 SELECT * FROM chksetconfig();
- db  |     role     |  rolkeyword  |         setconfig         
------+--------------+--------------+---------------------------
+ db  |     role     |  rolkeyword  |                       setconfig                        
+-----+--------------+--------------+--------------------------------------------------------
  ALL | Public       | -            | {application_name=BARBAR}
  ALL | current_user | -            | {application_name=FOOFOO}
- ALL | testrol1     | session_user | {application_name=SLAM}
+ ALL | testrol1     | session_user | {application_name=SLAM,log_min_duration_statement=100}
  ALL | testrol2     | current_user | {application_name=FOO}
 (4 rows)
 
 ALTER USER CURRENT_USER RESET application_name;
-ALTER USER SESSION_USER RESET application_name;
+ALTER USER SESSION_USER RESET (application_name, log_min_duration_statement, log_duration);
 ALTER USER "current_user" RESET application_name;
 ALTER USER "Public" RESET application_name;
 ALTER USER ALL RESET application_name;
diff --git a/src/test/regress/sql/rolenames.sql b/src/test/regress/sql/rolenames.sql
index e8c6b33..fae0b3b 100644
--- a/src/test/regress/sql/rolenames.sql
+++ b/src/test/regress/sql/rolenames.sql
@@ -127,7 +127,7 @@ ALTER USER nonexistent WITH NOREPLICATION; -- error
 --  ALTER ROLE SET/RESET
 SELECT * FROM chksetconfig();
 ALTER ROLE CURRENT_USER SET application_name to 'FOO';
-ALTER ROLE SESSION_USER SET application_name to 'BAR';
+ALTER ROLE SESSION_USER SET (application_name = 'BAR', log_min_duration_statement = 100);
 ALTER ROLE "current_user" SET application_name to 'FOOFOO';
 ALTER ROLE "Public" SET application_name to 'BARBAR';
 ALTER ROLE ALL SET application_name to 'SLAP';
@@ -135,7 +135,7 @@ SELECT * FROM chksetconfig();
 ALTER ROLE testrol1 SET application_name to 'SLAM';
 SELECT * FROM chksetconfig();
 ALTER ROLE CURRENT_USER RESET application_name;
-ALTER ROLE SESSION_USER RESET application_name;
+ALTER ROLE SESSION_USER RESET (application_name, log_min_duration_statement, log_duration);
 ALTER ROLE "current_user" RESET application_name;
 ALTER ROLE "Public" RESET application_name;
 ALTER ROLE ALL RESET application_name;
@@ -150,7 +150,7 @@ ALTER ROLE nonexistent SET application_name to 'BOMB'; -- error
 --  ALTER USER SET/RESET
 SELECT * FROM chksetconfig();
 ALTER USER CURRENT_USER SET application_name to 'FOO';
-ALTER USER SESSION_USER SET application_name to 'BAR';
+ALTER USER SESSION_USER SET (application_name = 'BAR', log_min_duration_statement = 100);
 ALTER USER "current_user" SET application_name to 'FOOFOO';
 ALTER USER "Public" SET application_name to 'BARBAR';
 ALTER USER ALL SET application_name to 'SLAP';
@@ -158,7 +158,7 @@ SELECT * FROM chksetconfig();
 ALTER USER testrol1 SET application_name to 'SLAM';
 SELECT * FROM chksetconfig();
 ALTER USER CURRENT_USER RESET application_name;
-ALTER USER SESSION_USER RESET application_name;
+ALTER USER SESSION_USER RESET (application_name, log_min_duration_statement, log_duration);
 ALTER USER "current_user" RESET application_name;
 ALTER USER "Public" RESET application_name;
 ALTER USER ALL RESET application_name;
