diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index d360fc4d58..68098ed5d5 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -6379,6 +6379,32 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-default-transaction-rollback-scope" xreflabel="default_transaction_rollback_scope">
+      <term><varname>default_transaction_rollback_scope</varname> (<type>enum</type>)
+      <indexterm>
+       <primary>transaction rollback scope</primary>
+       <secondary>setting default</secondary>
+      </indexterm>
+      <indexterm>
+       <primary><varname>default_transaction_rollback_scope</> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        This parameter controls which range of operations
+        to roll back when an SQL statement fails.
+        <quote>transaction</quote> rolls back the entire
+        transaction or current subtransaction.
+        <quote>statement</quote> rolls back the failed SQL statement.
+        The default is <quote>transaction</quote>.
+       </para>
+
+       <para>
+        Consult <xref linkend="sql-set-transaction"> for more information.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-default-transaction-read-only" xreflabel="default_transaction_read_only">
       <term><varname>default_transaction_read_only</varname> (<type>boolean</type>)
       <indexterm>
diff --git a/doc/src/sgml/ref/set_transaction.sgml b/doc/src/sgml/ref/set_transaction.sgml
index 3ab1e6f771..e32914525a 100644
--- a/doc/src/sgml/ref/set_transaction.sgml
+++ b/doc/src/sgml/ref/set_transaction.sgml
@@ -10,6 +10,11 @@
  </indexterm>
 
  <indexterm>
+  <primary>transaction rollback scope</primary>
+  <secondary>setting</secondary>
+ </indexterm>
+
+ <indexterm>
   <primary>read-only transaction</primary>
   <secondary>setting</secondary>
  </indexterm>
@@ -39,6 +44,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION <replaceable class="parameter">transa
 <phrase>where <replaceable class="parameter">transaction_mode</replaceable> is one of:</phrase>
 
     ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
+    ROLLBACK SCOPE { TRANSACTION | STATEMENT }
     READ WRITE | READ ONLY
     [ NOT ] DEFERRABLE
 </synopsis>
@@ -59,8 +65,8 @@ SET SESSION CHARACTERISTICS AS TRANSACTION <replaceable class="parameter">transa
 
   <para>
    The available transaction characteristics are the transaction
-   isolation level, the transaction access mode (read/write or
-   read-only), and the deferrable mode.
+   isolation level, the rollback scope,
+   the transaction access mode (read/write or read-only), and the deferrable mode.
    In addition, a snapshot can be selected, though only for the current
    transaction, not as a session default.
   </para>
@@ -123,6 +129,36 @@ SET SESSION CHARACTERISTICS AS TRANSACTION <replaceable class="parameter">transa
    isolation and concurrency control.
   </para>
 
+tunatuna
+  <para>
+   The isolation level of a transaction determines what data the
+   The rollback scope of a transaction determines which range of
+   operations to roll back when an SQL statement fails:
+
+   <variablelist>
+    <varlistentry>
+     <term><literal>TRANSACTION</literal></term>
+     <listitem>
+      <para>
+       A statement can only see rows committed before it began. This
+       Rolls back the entire transaction or current subtransaction.
+       This is the default.
+      </para>
+     </listitem>
+    </varlistentry>
+
+    <varlistentry>
+     <term><literal>STATEMENT</literal></term>
+     <listitem>
+      <para>
+       All statements of the current transaction can only see rows committed
+       Rolls back the failed SQL statement.
+      </para>
+     </listitem>
+    </varlistentry>
+   </variablelist>
+  </para>
+
   <para>
    The transaction access mode determines whether the transaction is
    read/write or read-only.  Read/write is the default.  When a
@@ -200,6 +236,7 @@ SET SESSION CHARACTERISTICS AS TRANSACTION <replaceable class="parameter">transa
   <para>
    The session default transaction modes can also be set by setting the
    configuration parameters <xref linkend="guc-default-transaction-isolation">,
+   <xref linkend="guc-default-transaction-rollback-scope">,
    <xref linkend="guc-default-transaction-read-only">, and
    <xref linkend="guc-default-transaction-deferrable">.
    (In fact <command>SET SESSION CHARACTERISTICS</command> is just a
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 8203388fa8..a4ddba4c4c 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -73,6 +73,9 @@
 int			DefaultXactIsoLevel = XACT_READ_COMMITTED;
 int			XactIsoLevel;
 
+int			DefaultXactRollbackScope = XACT_SCOPE_XACT;
+int			XactRollbackScope;
+
 bool		DefaultXactReadOnly = false;
 bool		XactReadOnly;
 
@@ -1839,6 +1842,7 @@ StartTransaction(void)
 	}
 	XactDeferrable = DefaultXactDeferrable;
 	XactIsoLevel = DefaultXactIsoLevel;
+	XactRollbackScope = DefaultXactRollbackScope;
 	forceSyncCommit = false;
 	MyXactFlags = 0;
 
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 3ed1c56e82..ac8eafd90b 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -608,6 +608,58 @@ show_XactIsoLevel(void)
 }
 
 /*
+ * SET TRANSACTION ROLLBACK SCOPE
+ */
+bool
+check_XactRollbackScope(char **newval, void **extra, GucSource source)
+{
+	int			newXactRollbackScope;
+
+	if (strcmp(*newval, "transaction") == 0)
+	{
+		newXactRollbackScope = XACT_SCOPE_XACT;
+	}
+	else if (strcmp(*newval, "statement") == 0)
+	{
+		newXactRollbackScope = XACT_SCOPE_STMT;
+	}
+	else if (strcmp(*newval, "default") == 0)
+	{
+		newXactRollbackScope = DefaultXactRollbackScope;
+	}
+	else
+		return false;
+
+	*extra = malloc(sizeof(int));
+	if (!*extra)
+		return false;
+	*((int *) *extra) = newXactRollbackScope;
+
+	return true;
+}
+
+void
+assign_XactRollbackScope(const char *newval, void *extra)
+{
+	XactRollbackScope = *((int *) extra);
+}
+
+const char *
+show_XactRollbackScope(void)
+{
+	/* We need this because we don't want to show "default". */
+	switch (XactRollbackScope)
+	{
+		case XACT_SCOPE_XACT:
+			return "transaction";
+		case XACT_SCOPE_STMT:
+			return "statement";
+		default:
+			return "bogus";
+	}
+}
+
+/*
  * SET TRANSACTION [NOT] DEFERRABLE
  */
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 4c83a63f7d..db71c764dd 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -352,7 +352,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <node>	RowSecurityOptionalWithCheck RowSecurityOptionalExpr
 %type <list>	RowSecurityDefaultToRole RowSecurityOptionalToRole
 
-%type <str>		iso_level opt_encoding
+%type <str>		iso_level rollback_scope opt_encoding
 %type <rolespec> grantee
 %type <list>	grantee_list
 %type <accesspriv> privilege
@@ -668,7 +668,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 	RESET RESTART RESTRICT RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP
 	ROW ROWS RULE
 
-	SAVEPOINT SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES
+	SAVEPOINT SCHEMA SCHEMAS SCOPE SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES
 	SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW
 	SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SQL_P STABLE STANDALONE_P
 	START STATEMENT STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P
@@ -1557,6 +1557,10 @@ iso_level:	READ UNCOMMITTED						{ $$ = "read uncommitted"; }
 			| SERIALIZABLE							{ $$ = "serializable"; }
 		;
 
+rollback_scope:	TRANSACTION						{ $$ = "transaction"; }
+			| STATEMENT							{ $$ = "statement"; }
+		;
+
 opt_boolean_or_string:
 			TRUE_P									{ $$ = "true"; }
 			| FALSE_P								{ $$ = "false"; }
@@ -9596,6 +9600,9 @@ transaction_mode_item:
 			ISOLATION LEVEL iso_level
 					{ $$ = makeDefElem("transaction_isolation",
 									   makeStringConst($3, @3), @1); }
+			| ROLLBACK SCOPE rollback_scope
+					{ $$ = makeDefElem("transaction_rollback_scope",
+									   makeStringConst($3, @3), @1); }
 			| READ ONLY
 					{ $$ = makeDefElem("transaction_read_only",
 									   makeIntConst(TRUE, @1), @1); }
@@ -14807,6 +14814,7 @@ unreserved_keyword:
 			| SAVEPOINT
 			| SCHEMA
 			| SCHEMAS
+			| SCOPE
 			| SCROLL
 			| SEARCH
 			| SECOND_P
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 2c7260e564..fe2ad5da2e 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -149,6 +149,13 @@ static bool ignore_till_sync = false;
 static bool stmt_timeout_active = false;
 
 /*
+ * Flag to keep track of whether we have started a transaction.
+ * Flag to keep track of whether we have created a savepoint
+ * for statement rollback.
+ */
+static bool stmt_savepoint_created = false;
+
+/*
  * If an unnamed prepared statement exists, it's stored here.
  * We keep it separate from the hashtable kept by commands/prepare.c
  * in order to reduce overhead for short-lived queries.
@@ -923,6 +930,16 @@ exec_simple_query(const char *query_string)
 	start_xact_command();
 
 	/*
+	 * Create a savepoint for statement rollback.
+	 */
+	if (XactRollbackScope == XACT_SCOPE_STMT &&
+		IsTransactionBlock())
+	{
+		BeginInternalSubTransaction(NULL);
+		stmt_savepoint_created = true;
+	}
+
+	/*
 	 * Zap any pre-existing unnamed statement.  (While not strictly necessary,
 	 * it seems best to define simple-Query mode as if it used the unnamed
 	 * statement and portal; this ensures we recover any storage used by prior
@@ -1022,6 +1039,17 @@ exec_simple_query(const char *query_string)
 		if (use_implicit_block)
 			BeginImplicitTransactionBlock();
 
+		/*
+		 * Create a savepoint for statement rollback.
+		 */
+		if (XactRollbackScope == XACT_SCOPE_STMT &&
+			!stmt_savepoint_created &&
+			IsTransactionBlock())
+		{
+			BeginInternalSubTransaction(NULL);
+			stmt_savepoint_created = true;
+		}
+
 		/* If we got a cancel signal in parsing or prior command, quit */
 		CHECK_FOR_INTERRUPTS();
 
@@ -1143,6 +1171,7 @@ exec_simple_query(const char *query_string)
 			if (use_implicit_block)
 				EndImplicitTransactionBlock();
 			finish_xact_command();
+			stmt_savepoint_created = false;
 		}
 		else if (IsA(parsetree->stmt, TransactionStmt))
 		{
@@ -1159,6 +1188,15 @@ exec_simple_query(const char *query_string)
 			 * those that start or end a transaction block.
 			 */
 			CommandCounterIncrement();
+
+			/*
+			 * Delete the savepoint for statement rollback.
+			 */
+			if (stmt_savepoint_created)
+			{
+				ReleaseCurrentSubTransaction();
+				stmt_savepoint_created = false;
+			}
 		}
 
 		/*
@@ -1171,6 +1209,15 @@ exec_simple_query(const char *query_string)
 	}							/* end loop over parsetrees */
 
 	/*
+	 * Delete the savepoint for statement rollback.
+	 */
+	if (stmt_savepoint_created)
+	{
+		ReleaseCurrentSubTransaction();
+		stmt_savepoint_created = false;
+	}
+
+	/*
 	 * Close down transaction statement, if one is open.  (This will only do
 	 * something if the parsetree list was empty; otherwise the last loop
 	 * iteration already did it.)
@@ -1258,6 +1305,16 @@ exec_parse_message(const char *query_string,	/* string to execute */
 	start_xact_command();
 
 	/*
+	 * Create a savepoint for statement rollback.
+	 */
+	if (XactRollbackScope == XACT_SCOPE_STMT &&
+		IsTransactionBlock())
+	{
+		BeginInternalSubTransaction(NULL);
+		stmt_savepoint_created = true;
+	}
+
+	/*
 	 * Switch to appropriate context for constructing parsetrees.
 	 *
 	 * We have two strategies depending on whether the prepared statement is
@@ -1435,6 +1492,12 @@ exec_parse_message(const char *query_string,	/* string to execute */
 	MemoryContextSwitchTo(oldcontext);
 
 	/*
+	 * Delete the savepoint for statement rollback.
+	 */
+	ReleaseCurrentSubTransaction();
+	stmt_savepoint_created = false;
+
+	/*
 	 * We do NOT close the open transaction command here; that only happens
 	 * when the client sends Sync.  Instead, do CommandCounterIncrement just
 	 * in case something happened during parse/plan.
@@ -1546,6 +1609,16 @@ exec_bind_message(StringInfo input_message)
 	 */
 	start_xact_command();
 
+	/*
+	 * Create a savepoint for statement rollback.
+	 */
+	if (XactRollbackScope == XACT_SCOPE_STMT &&
+		IsTransactionBlock())
+	{
+		BeginInternalSubTransaction(NULL);
+		stmt_savepoint_created = true;
+	}
+
 	/* Switch back to message context */
 	MemoryContextSwitchTo(MessageContext);
 
@@ -1823,6 +1896,12 @@ exec_bind_message(StringInfo input_message)
 	PortalSetResultFormat(portal, numRFormats, rformats);
 
 	/*
+	 * Delete the savepoint for statement rollback.
+	 */
+	ReleaseCurrentSubTransaction();
+	stmt_savepoint_created = false;
+
+	/*
 	 * Send BindComplete.
 	 */
 	if (whereToSendOutput == DestRemote)
@@ -1884,6 +1963,16 @@ exec_execute_message(const char *portal_name, long max_rows)
 	if (dest == DestRemote)
 		dest = DestRemoteExecute;
 
+	/*
+	 * Create a savepoint for statement rollback.
+	 */
+	if (XactRollbackScope == XACT_SCOPE_STMT &&
+		IsTransactionBlock())
+	{
+		BeginInternalSubTransaction(NULL);
+		stmt_savepoint_created = true;
+	}
+
 	portal = GetPortalByName(portal_name);
 	if (!PortalIsValid(portal))
 		ereport(ERROR,
@@ -2026,6 +2115,7 @@ exec_execute_message(const char *portal_name, long max_rows)
 			 * will start a new xact command for the next command (if any).
 			 */
 			finish_xact_command();
+			stmt_savepoint_created = false;
 		}
 		else
 		{
@@ -2050,6 +2140,15 @@ exec_execute_message(const char *portal_name, long max_rows)
 	}
 
 	/*
+	 * Delete the savepoint for statement rollback.
+	 */
+	if (stmt_savepoint_created)
+	{
+		ReleaseCurrentSubTransaction();
+		stmt_savepoint_created = false;
+	}
+
+	/*
 	 * Emit duration logging if appropriate.
 	 */
 	switch (check_log_duration(msec_str, was_logged))
@@ -2327,6 +2426,16 @@ exec_describe_statement_message(const char *stmt_name)
 	 */
 	start_xact_command();
 
+	/*
+	 * Create a savepoint for statement rollback.
+	 */
+	if (XactRollbackScope == XACT_SCOPE_STMT &&
+		IsTransactionBlock())
+	{
+		BeginInternalSubTransaction(NULL);
+		stmt_savepoint_created = true;
+	}
+
 	/* Switch back to message context */
 	MemoryContextSwitchTo(MessageContext);
 
@@ -2368,6 +2477,12 @@ exec_describe_statement_message(const char *stmt_name)
 						"commands ignored until end of transaction block"),
 				 errdetail_abort()));
 
+	/*
+	 * Delete the savepoint for statement rollback.
+	 */
+	ReleaseCurrentSubTransaction();
+	stmt_savepoint_created = false;
+
 	if (whereToSendOutput != DestRemote)
 		return;					/* can't actually do anything... */
 
@@ -2422,6 +2537,16 @@ exec_describe_portal_message(const char *portal_name)
 	 */
 	start_xact_command();
 
+	/*
+	 * Create a savepoint for statement rollback.
+	 */
+	if (XactRollbackScope == XACT_SCOPE_STMT &&
+		IsTransactionBlock())
+	{
+		BeginInternalSubTransaction(NULL);
+		stmt_savepoint_created = true;
+	}
+
 	/* Switch back to message context */
 	MemoryContextSwitchTo(MessageContext);
 
@@ -2447,6 +2572,12 @@ exec_describe_portal_message(const char *portal_name)
 						"commands ignored until end of transaction block"),
 				 errdetail_abort()));
 
+	/*
+	 * Delete the savepoint for statement rollback.
+	 */
+	ReleaseCurrentSubTransaction();
+	stmt_savepoint_created = false;
+
 	if (whereToSendOutput != DestRemote)
 		return;					/* can't actually do anything... */
 
@@ -3929,6 +4060,13 @@ PostgresMain(int argc, char *argv[],
 		 */
 		AbortCurrentTransaction();
 
+		/* Roll back the failed statement, if requested. */
+		if (stmt_savepoint_created)
+		{
+			RollbackAndReleaseCurrentSubTransaction();
+			stmt_savepoint_created = false;
+		}
+
 		if (am_walsender)
 			WalSndErrorCleanup();
 
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 82a707af7b..c833f53665 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -420,6 +420,10 @@ standard_ProcessUtility(PlannedStmt *pstmt,
 									SetPGVariable("transaction_isolation",
 												  list_make1(item->arg),
 												  true);
+								if (strcmp(item->defname, "transaction_rollback_scope") == 0)
+									SetPGVariable("transaction_rollback_scope",
+												  list_make1(item->arg),
+												  true);
 								else if (strcmp(item->defname, "transaction_read_only") == 0)
 									SetPGVariable("transaction_read_only",
 												  list_make1(item->arg),
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 65372d7cc5..a2c485d11f 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -278,6 +278,12 @@ static const struct config_enum_entry isolation_level_options[] = {
 	{NULL, 0}
 };
 
+static const struct config_enum_entry rollback_scope_options[] = {
+	{"transaction", XACT_SCOPE_XACT, false},
+	{"statement", XACT_SCOPE_STMT, false},
+	{NULL, 0}
+};
+
 static const struct config_enum_entry session_replication_role_options[] = {
 	{"origin", SESSION_REPLICATION_ROLE_ORIGIN, false},
 	{"replica", SESSION_REPLICATION_ROLE_REPLICA, false},
@@ -505,6 +511,7 @@ static char *timezone_string;
 static char *log_timezone_string;
 static char *timezone_abbreviations_string;
 static char *XactIsoLevel_string;
+static char *XactRollbackScope_string;
 static char *data_directory;
 static char *session_authorization_string;
 static int	max_function_args;
@@ -3407,6 +3414,17 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
+		{"transaction_rollback_scope", PGC_USERSET, CLIENT_CONN_STATEMENT,
+			gettext_noop("Sets the scope of rollback when the current transaction aborts."),
+			NULL,
+			GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
+		},
+		&XactRollbackScope_string,
+		"default",
+		check_XactRollbackScope, assign_XactRollbackScope, show_XactRollbackScope
+	},
+
+	{
 		{"unix_socket_group", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
 			gettext_noop("Sets the owning group of the Unix-domain socket."),
 			gettext_noop("The owning user of the socket is always the user "
@@ -3710,6 +3728,16 @@ static struct config_enum ConfigureNamesEnum[] =
 	},
 
 	{
+		{"default_transaction_rollback_scope", PGC_USERSET, CLIENT_CONN_STATEMENT,
+			gettext_noop("Sets the scope of rollback when the current transaction aborts."),
+			NULL
+		},
+		&DefaultXactRollbackScope,
+		XACT_SCOPE_XACT, rollback_scope_options,
+		NULL, NULL, NULL
+	},
+
+	{
 		{"IntervalStyle", PGC_USERSET, CLIENT_CONN_LOCALE,
 			gettext_noop("Sets the display format for interval values."),
 			NULL,
@@ -4507,6 +4535,8 @@ InitializeGUCOptions(void)
 	 */
 	SetConfigOption("transaction_isolation", "default",
 					PGC_POSTMASTER, PGC_S_OVERRIDE);
+	SetConfigOption("transaction_rollback_scope", "default",
+					PGC_POSTMASTER, PGC_S_OVERRIDE);
 	SetConfigOption("transaction_read_only", "no",
 					PGC_POSTMASTER, PGC_S_OVERRIDE);
 	SetConfigOption("transaction_deferrable", "no",
@@ -7337,6 +7367,9 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
 					if (strcmp(item->defname, "transaction_isolation") == 0)
 						SetPGVariable("transaction_isolation",
 									  list_make1(item->arg), stmt->is_local);
+					else if (strcmp(item->defname, "transaction_rollback_scope") == 0)
+						SetPGVariable("transaction_isolation",
+									  list_make1(item->arg), stmt->is_local);
 					else if (strcmp(item->defname, "transaction_read_only") == 0)
 						SetPGVariable("transaction_read_only",
 									  list_make1(item->arg), stmt->is_local);
@@ -7359,6 +7392,9 @@ ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
 					if (strcmp(item->defname, "transaction_isolation") == 0)
 						SetPGVariable("default_transaction_isolation",
 									  list_make1(item->arg), stmt->is_local);
+					else if (strcmp(item->defname, "transaction_rollback_scope") == 0)
+						SetPGVariable("default_transaction_isolation",
+									  list_make1(item->arg), stmt->is_local);
 					else if (strcmp(item->defname, "transaction_read_only") == 0)
 						SetPGVariable("default_transaction_read_only",
 									  list_make1(item->arg), stmt->is_local);
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 368b280c8a..a3aa64067f 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -545,6 +545,7 @@
 					# only default tablespace
 #check_function_bodies = on
 #default_transaction_isolation = 'read committed'
+#default_transaction_rollback_scope = 'transaction'
 #default_transaction_read_only = off
 #default_transaction_deferrable = off
 #session_replication_role = 'origin'
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index f2c10f905f..cb7ab74376 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -43,6 +43,15 @@ extern PGDLLIMPORT int XactIsoLevel;
 #define IsolationUsesXactSnapshot() (XactIsoLevel >= XACT_REPEATABLE_READ)
 #define IsolationIsSerializable() (XactIsoLevel == XACT_SERIALIZABLE)
 
+/*
+ * Xact rollback scopes
+ */
+#define XACT_SCOPE_XACT 0
+#define XACT_SCOPE_STMT 1
+
+extern int	DefaultXactRollbackScope;
+extern PGDLLIMPORT int XactRollbackScope;
+
 /* Xact read-only state */
 extern bool DefaultXactReadOnly;
 extern bool XactReadOnly;
diff --git a/src/include/commands/variable.h b/src/include/commands/variable.h
index 575339a6d8..69dd0c07fd 100644
--- a/src/include/commands/variable.h
+++ b/src/include/commands/variable.h
@@ -25,6 +25,9 @@ extern bool check_transaction_read_only(bool *newval, void **extra, GucSource so
 extern bool check_XactIsoLevel(char **newval, void **extra, GucSource source);
 extern void assign_XactIsoLevel(const char *newval, void *extra);
 extern const char *show_XactIsoLevel(void);
+extern bool check_XactRollbackScope(char **newval, void **extra, GucSource source);
+extern void assign_XactRollbackScope(const char *newval, void *extra);
+extern const char *show_XactRollbackScope(void);
 extern bool check_transaction_deferrable(bool *newval, void **extra, GucSource source);
 extern bool check_random_seed(double *newval, void **extra, GucSource source);
 extern void assign_random_seed(double newval, void *extra);
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index f50e45e886..db3bf834d2 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -346,6 +346,7 @@ PG_KEYWORD("rule", RULE, UNRESERVED_KEYWORD)
 PG_KEYWORD("savepoint", SAVEPOINT, UNRESERVED_KEYWORD)
 PG_KEYWORD("schema", SCHEMA, UNRESERVED_KEYWORD)
 PG_KEYWORD("schemas", SCHEMAS, UNRESERVED_KEYWORD)
+PG_KEYWORD("scope", SCOPE, UNRESERVED_KEYWORD)
 PG_KEYWORD("scroll", SCROLL, UNRESERVED_KEYWORD)
 PG_KEYWORD("search", SEARCH, UNRESERVED_KEYWORD)
 PG_KEYWORD("second", SECOND_P, UNRESERVED_KEYWORD)
