diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 169a385a9cc9decdfadfde16a86ec95eaea7e397..6355300d9d33e5cc332ef49f7a1415458c63bf12 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -17119,6 +17119,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); <primary>txid_current</primary> </indexterm> + <indexterm> + <primary>txid_current_if_assigned</primary> + </indexterm> + <indexterm> <primary>txid_current_snapshot</primary> </indexterm> @@ -17159,6 +17163,11 @@ SELECT collation for ('foo' COLLATE "de_DE"); <entry><type>bigint</type></entry> <entry>get current transaction ID, assigning a new one if the current transaction does not have one</entry> </row> + <row> + <entry><literal><function>txid_current_if_assigned()</function></literal></entry> + <entry><type>bigint</type></entry> + <entry>same as <function>txid_current()</function> but returns null instead of assigning an xid if none is already assigned</entry> + </row> <row> <entry><literal><function>txid_current_snapshot()</function></literal></entry> <entry><type>txid_snapshot</type></entry> diff --git a/src/backend/utils/adt/txid.c b/src/backend/utils/adt/txid.c index c2069a9923b9df22b361dfbd50c1ea980e0fe458..276075e293c0242b71bf41b8c2c4c5925cbc5a0e 100644 --- a/src/backend/utils/adt/txid.c +++ b/src/backend/utils/adt/txid.c @@ -376,6 +376,27 @@ txid_current(PG_FUNCTION_ARGS) PG_RETURN_INT64(val); } +/* + * Same as txid_current() but doesn't assign a new xid if there isn't one + * yet. + */ +Datum +txid_current_if_assigned(PG_FUNCTION_ARGS) +{ + txid val; + TxidEpoch state; + TransactionId topxid = GetTopTransactionIdIfAny(); + + if (topxid == InvalidTransactionId) + PG_RETURN_NULL(); + + load_xid_epoch(&state); + + val = convert_xid(topxid, &state); + + PG_RETURN_INT64(val); +} + /* * txid_current_snapshot() returns txid_snapshot * diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 6fed7a0d19897940292e66971c53695369b1f68e..050a98c39720d2faeb654d1ecf9ca65014c8aedd 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -4904,6 +4904,8 @@ DATA(insert OID = 2942 ( txid_snapshot_send PGNSP PGUID 12 1 0 0 0 f f f f t DESCR("I/O"); DATA(insert OID = 2943 ( txid_current PGNSP PGUID 12 1 0 0 0 f f f f t f s u 0 0 20 "" _null_ _null_ _null_ _null_ _null_ txid_current _null_ _null_ _null_ )); DESCR("get current transaction ID"); +DATA(insert OID = 3348 ( txid_current_if_assigned PGNSP PGUID 12 1 0 0 0 f f f f t f s u 0 0 20 "" _null_ _null_ _null_ _null_ _null_ txid_current_if_assigned _null_ _null_ _null_ )); +DESCR("get current transaction ID"); DATA(insert OID = 2944 ( txid_current_snapshot PGNSP PGUID 12 1 0 0 0 f f f f t f s s 0 0 2970 "" _null_ _null_ _null_ _null_ _null_ txid_current_snapshot _null_ _null_ _null_ )); DESCR("get current snapshot"); DATA(insert OID = 2945 ( txid_snapshot_xmin PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 20 "2970" _null_ _null_ _null_ _null_ _null_ txid_snapshot_xmin _null_ _null_ _null_ )); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 40e25c8824719f3da8ff71173535ab4cb7aba7c2..2ae212a9c3f48130821fe2f5bb1f2d9fdc08c60e 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -1221,6 +1221,7 @@ extern Datum txid_snapshot_out(PG_FUNCTION_ARGS); extern Datum txid_snapshot_recv(PG_FUNCTION_ARGS); extern Datum txid_snapshot_send(PG_FUNCTION_ARGS); extern Datum txid_current(PG_FUNCTION_ARGS); +extern Datum txid_current_if_assigned(PG_FUNCTION_ARGS); extern Datum txid_current_snapshot(PG_FUNCTION_ARGS); extern Datum txid_snapshot_xmin(PG_FUNCTION_ARGS); extern Datum txid_snapshot_xmax(PG_FUNCTION_ARGS); diff --git a/src/test/regress/expected/txid.out b/src/test/regress/expected/txid.out index ddd217eb1024f6ddb595155838ff698d36e4618f..802ccb949f89da3e9531ff57000805e37ac520eb 100644 --- a/src/test/regress/expected/txid.out +++ b/src/test/regress/expected/txid.out @@ -238,3 +238,19 @@ SELECT txid_snapshot '1:9223372036854775808:3'; ERROR: invalid input syntax for type txid_snapshot: "1:9223372036854775808:3" LINE 1: SELECT txid_snapshot '1:9223372036854775808:3'; ^ +-- test txid_current_if_assigned +BEGIN; +SELECT txid_current_if_assigned() IS NULL; + ?column? +---------- + t +(1 row) + +SELECT txid_current() \gset +SELECT txid_current_if_assigned() IS NOT DISTINCT FROM BIGINT :'txid_current'; + ?column? +---------- + t +(1 row) + +COMMIT; diff --git a/src/test/regress/sql/txid.sql b/src/test/regress/sql/txid.sql index b6650b922e6d4b0df87fde088be491600b386e2f..4aefd9e64d1bb43ceeada58c6a19f623971f4465 100644 --- a/src/test/regress/sql/txid.sql +++ b/src/test/regress/sql/txid.sql @@ -52,3 +52,10 @@ select txid_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010 -- test 64bit overflow SELECT txid_snapshot '1:9223372036854775807:3'; SELECT txid_snapshot '1:9223372036854775808:3'; + +-- test txid_current_if_assigned +BEGIN; +SELECT txid_current_if_assigned() IS NULL; +SELECT txid_current() \gset +SELECT txid_current_if_assigned() IS NOT DISTINCT FROM BIGINT :'txid_current'; +COMMIT;