Skip to content

Instantly share code, notes, and snippets.

@divyenduz
Created September 25, 2025 09:05
Show Gist options
  • Select an option

  • Save divyenduz/a1d21fb20585c1d32c9edf90f96f8fc2 to your computer and use it in GitHub Desktop.

Select an option

Save divyenduz/a1d21fb20585c1d32c9edf90f96f8fc2 to your computer and use it in GitHub Desktop.
Postgres amen
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 9fd48acb1f8..dc68c1723ac 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -698,7 +698,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
/* ordinary key words in alphabetical order */
%token <keyword> ABORT_P ABSENT ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
- AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
+ AGGREGATE ALL ALSO ALTER ALWAYS AMEN ANALYSE ANALYZE AND ANY ARRAY AS ASC
ASENSITIVE ASSERTION ASSIGNMENT ASYMMETRIC ATOMIC AT ATTACH ATTRIBUTE AUTHORIZATION
BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT
@@ -11208,6 +11208,16 @@ TransactionStmt:
n->location = -1;
$$ = (Node *) n;
}
+ | AMEN opt_transaction opt_transaction_chain
+ {
+ TransactionStmt *n = makeNode(TransactionStmt);
+
+ n->kind = TRANS_STMT_COMMIT;
+ n->options = NIL;
+ n->chain = $3;
+ n->location = -1;
+ $$ = (Node *) n;
+ }
| ROLLBACK opt_transaction opt_transaction_chain
{
TransactionStmt *n = makeNode(TransactionStmt);
@@ -11281,6 +11291,15 @@ TransactionStmt:
n->location = @3;
$$ = (Node *) n;
}
+ | AMEN PREPARED Sconst
+ {
+ TransactionStmt *n = makeNode(TransactionStmt);
+
+ n->kind = TRANS_STMT_COMMIT_PREPARED;
+ n->gid = $3;
+ n->location = @3;
+ $$ = (Node *) n;
+ }
| ROLLBACK PREPARED Sconst
{
TransactionStmt *n = makeNode(TransactionStmt);
@@ -17743,6 +17762,7 @@ unreserved_keyword:
| ALSO
| ALTER
| ALWAYS
+ | AMEN
| ASENSITIVE
| ASSERTION
| ASSIGNMENT
@@ -18285,6 +18305,7 @@ bare_label_keyword:
| ALSO
| ALTER
| ALWAYS
+ | AMEN
| ANALYSE
| ANALYZE
| AND
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index a4af3f717a1..9659447c738 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -38,6 +38,7 @@ PG_KEYWORD("all", ALL, RESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("also", ALSO, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("alter", ALTER, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("always", ALWAYS, UNRESERVED_KEYWORD, BARE_LABEL)
+PG_KEYWORD("amen", AMEN, UNRESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("analyse", ANALYSE, RESERVED_KEYWORD, BARE_LABEL) /* British spelling */
PG_KEYWORD("analyze", ANALYZE, RESERVED_KEYWORD, BARE_LABEL)
PG_KEYWORD("and", AND, RESERVED_KEYWORD, BARE_LABEL)
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index 17568d82554..0fc8905d320 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -210,7 +210,7 @@ static void check_raise_parameters(PLpgSQL_stmt_raise *stmt);
%type <stmt> stmt_return stmt_raise stmt_assert stmt_execsql
%type <stmt> stmt_dynexecute stmt_for stmt_perform stmt_call stmt_getdiag
%type <stmt> stmt_open stmt_fetch stmt_move stmt_close stmt_null
-%type <stmt> stmt_commit stmt_rollback
+%type <stmt> stmt_amen stmt_commit stmt_rollback
%type <stmt> stmt_case stmt_foreach_a
%type <list> proc_exceptions
@@ -265,6 +265,7 @@ static void check_raise_parameters(PLpgSQL_stmt_raise *stmt);
%token <keyword> K_ABSOLUTE
%token <keyword> K_ALIAS
%token <keyword> K_ALL
+%token <keyword> K_AMEN
%token <keyword> K_AND
%token <keyword> K_ARRAY
%token <keyword> K_ASSERT
@@ -887,6 +888,8 @@ proc_stmt : pl_block ';'
{ $$ = $1; }
| stmt_null
{ $$ = $1; }
+ | stmt_amen
+ { $$ = $1; }
| stmt_commit
{ $$ = $1; }
| stmt_rollback
@@ -2260,6 +2263,20 @@ stmt_commit : K_COMMIT opt_transaction_chain ';'
}
;
+stmt_amen : K_AMEN opt_transaction_chain ';'
+ {
+ PLpgSQL_stmt_commit *new;
+
+ new = palloc(sizeof(PLpgSQL_stmt_commit));
+ new->cmd_type = PLPGSQL_STMT_COMMIT;
+ new->lineno = plpgsql_location_to_lineno(@1, yyscanner);
+ new->stmtid = ++plpgsql_curr_compile->nstatements;
+ new->chain = $2;
+
+ $$ = (PLpgSQL_stmt *) new;
+ }
+ ;
+
stmt_rollback : K_ROLLBACK opt_transaction_chain ';'
{
PLpgSQL_stmt_rollback *new;
@@ -2510,6 +2527,7 @@ any_identifier : T_WORD
unreserved_keyword :
K_ABSOLUTE
| K_ALIAS
+ | K_AMEN
| K_AND
| K_ARRAY
| K_ASSERT
diff --git a/src/pl/plpgsql/src/pl_unreserved_kwlist.h b/src/pl/plpgsql/src/pl_unreserved_kwlist.h
index b48c5a645ff..f3ce0ce2389 100644
--- a/src/pl/plpgsql/src/pl_unreserved_kwlist.h
+++ b/src/pl/plpgsql/src/pl_unreserved_kwlist.h
@@ -29,6 +29,7 @@
/* name, value */
PG_KEYWORD("absolute", K_ABSOLUTE)
PG_KEYWORD("alias", K_ALIAS)
+PG_KEYWORD("amen", K_AMEN)
PG_KEYWORD("and", K_AND)
PG_KEYWORD("array", K_ARRAY)
PG_KEYWORD("assert", K_ASSERT)
diff --git a/src/test/regress/sql/transactions.sql b/src/test/regress/sql/transactions.sql
index 51ae1b31b30..6ba9688cae3 100644
--- a/src/test/regress/sql/transactions.sql
+++ b/src/test/regress/sql/transactions.sql
@@ -634,6 +634,29 @@ BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET TRANSACTION SNAPSHOT 'FFF-FFF-F';
ROLLBACK;
+-- Test AMEN statement (alias for COMMIT)
+BEGIN;
+CREATE TEMPORARY TABLE amen_test (id int);
+INSERT INTO amen_test VALUES (1);
+AMEN;
+
+-- Verify table was committed
+SELECT * FROM amen_test;
+
+-- Test AMEN with transaction chain
+BEGIN;
+INSERT INTO amen_test VALUES (2);
+AMEN AND CHAIN;
+INSERT INTO amen_test VALUES (3);
+COMMIT;
+
+-- Verify both inserts worked
+SELECT * FROM amen_test ORDER BY id;
+
+-- Test AMEN PREPARED
+PREPARE TRANSACTION 'test_amen';
+AMEN PREPARED 'test_amen';
+
-- Test for successful cleanup of an aborted transaction at session exit.
-- THIS MUST BE THE LAST TEST IN THIS FILE.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment