aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2020-04-07 11:33:56 +1200
committerThomas Munro <tmunro@postgresql.org>2020-04-07 12:04:32 +1200
commit4c04be9b05ad2ec5acd27c3417bf075c13cab134 (patch)
treea85e0f90b3b5fd059b4155d93f00bf58f54955ca /src
parentaeec457de8a8820368e343e791accffe24dc7198 (diff)
downloadpostgresql-4c04be9b05ad2ec5acd27c3417bf075c13cab134.tar.gz
postgresql-4c04be9b05ad2ec5acd27c3417bf075c13cab134.zip
Introduce xid8-based functions to replace txid_XXX.
The txid_XXX family of fmgr functions exposes 64 bit transaction IDs to users as int8. Now that we have an SQL type xid8 for FullTransactionId, define a new set of functions including pg_current_xact_id() and pg_current_snapshot() based on that. Keep the old functions around too, for now. It's a bit sneaky to use the same C functions for both, but since the binary representation is identical except for the signedness of the type, and since older functions are the ones using the wrong signedness, and since we'll presumably drop the older ones after a reasonable period of time, it seems reasonable to switch to FullTransactionId internally and share the code for both. Reviewed-by: Fujii Masao <masao.fujii@oss.nttdata.com> Reviewed-by: Takao Fujii <btfujiitkp@oss.nttdata.com> Reviewed-by: Yoshikazu Imai <imai.yoshikazu@fujitsu.com> Reviewed-by: Mark Dilger <mark.dilger@enterprisedb.com> Discussion: https://postgr.es/m/20190725000636.666m5mad25wfbrri%40alap3.anarazel.de
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/Makefile2
-rw-r--r--src/backend/utils/adt/xid8funcs.c (renamed from src/backend/utils/adt/txid.c)424
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/catalog/pg_proc.dat69
-rw-r--r--src/include/catalog/pg_type.dat5
-rw-r--r--src/test/modules/commit_ts/t/004_restart.pl6
-rw-r--r--src/test/modules/test_ddl_deparse/expected/create_table.out2
-rw-r--r--src/test/modules/test_ddl_deparse/sql/create_table.sql2
-rw-r--r--src/test/recovery/t/003_recovery_targets.pl2
-rw-r--r--src/test/recovery/t/011_crash_recovery.pl10
-rw-r--r--src/test/regress/expected/alter_table.out4
-rw-r--r--src/test/regress/expected/hs_standby_functions.out6
-rw-r--r--src/test/regress/expected/opr_sanity.out11
-rw-r--r--src/test/regress/expected/txid.out13
-rw-r--r--src/test/regress/expected/update.out6
-rw-r--r--src/test/regress/expected/xid.out326
-rw-r--r--src/test/regress/sql/alter_table.sql4
-rw-r--r--src/test/regress/sql/hs_standby_functions.sql4
-rw-r--r--src/test/regress/sql/txid.sql3
-rw-r--r--src/test/regress/sql/update.sql6
-rw-r--r--src/test/regress/sql/xid.sql104
-rw-r--r--src/tools/pgindent/typedefs.list1
22 files changed, 716 insertions, 296 deletions
diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile
index 13efa9338c1..5d2aca8cfe6 100644
--- a/src/backend/utils/adt/Makefile
+++ b/src/backend/utils/adt/Makefile
@@ -101,7 +101,6 @@ OBJS = \
tsvector.o \
tsvector_op.o \
tsvector_parser.o \
- txid.o \
uuid.o \
varbit.o \
varchar.o \
@@ -109,6 +108,7 @@ OBJS = \
version.o \
windowfuncs.o \
xid.o \
+ xid8funcs.o \
xml.o
jsonpath_scan.c: FLEXFLAGS = -CF -p -p
diff --git a/src/backend/utils/adt/txid.c b/src/backend/utils/adt/xid8funcs.c
index 33272f80308..616f187ad42 100644
--- a/src/backend/utils/adt/txid.c
+++ b/src/backend/utils/adt/xid8funcs.c
@@ -1,20 +1,25 @@
/*-------------------------------------------------------------------------
- * txid.c
+ * xid8funcs.c
*
* Export internal transaction IDs to user level.
*
- * Note that only top-level transaction IDs are ever converted to TXID.
- * This is important because TXIDs frequently persist beyond the global
+ * Note that only top-level transaction IDs are exposed to user sessions.
+ * This is important because xid8s frequently persist beyond the global
* xmin horizon, or may even be shipped to other machines, so we cannot
* rely on being able to correlate subtransaction IDs with their parents
* via functions such as SubTransGetTopmostTransaction().
*
+ * These functions are used to support the txid_XXX functions and the newer
+ * pg_current_xact, pg_current_snapshot and related fmgr functions, since the
+ * only difference between them is whether they expose xid8 or int8 values to
+ * users. The txid_XXX variants should eventually be dropped.
+ *
*
* Copyright (c) 2003-2020, PostgreSQL Global Development Group
* Author: Jan Wieck, Afilias USA INC.
* 64-bit txids: Marko Kreen, Skype Technologies
*
- * src/backend/utils/adt/txid.c
+ * src/backend/utils/adt/xid8funcs.c
*
*-------------------------------------------------------------------------
*/
@@ -34,25 +39,18 @@
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/snapmgr.h"
+#include "utils/xid8.h"
-/* txid will be signed int8 in database, so must limit to 63 bits */
-#define MAX_TXID ((uint64) PG_INT64_MAX)
-
-/* Use unsigned variant internally */
-typedef uint64 txid;
-
-/* sprintf format code for uint64 */
-#define TXID_FMT UINT64_FORMAT
/*
- * If defined, use bsearch() function for searching for txids in snapshots
+ * If defined, use bsearch() function for searching for xid8s in snapshots
* that have more than the specified number of values.
*/
#define USE_BSEARCH_IF_NXIP_GREATER 30
/*
- * Snapshot containing 8byte txids.
+ * Snapshot containing FullTransactionIds.
*/
typedef struct
{
@@ -63,39 +61,17 @@ typedef struct
*/
int32 __varsz;
- uint32 nxip; /* number of txids in xip array */
- txid xmin;
- txid xmax;
- /* in-progress txids, xmin <= xip[i] < xmax: */
- txid xip[FLEXIBLE_ARRAY_MEMBER];
-} TxidSnapshot;
-
-#define TXID_SNAPSHOT_SIZE(nxip) \
- (offsetof(TxidSnapshot, xip) + sizeof(txid) * (nxip))
-#define TXID_SNAPSHOT_MAX_NXIP \
- ((MaxAllocSize - offsetof(TxidSnapshot, xip)) / sizeof(txid))
-
-/*
- * Epoch values from xact.c
- */
-typedef struct
-{
- TransactionId last_xid;
- uint32 epoch;
-} TxidEpoch;
-
-
-/*
- * Fetch epoch data from xact.c.
- */
-static void
-load_xid_epoch(TxidEpoch *state)
-{
- FullTransactionId fullXid = ReadNextFullTransactionId();
+ uint32 nxip; /* number of fxids in xip array */
+ FullTransactionId xmin;
+ FullTransactionId xmax;
+ /* in-progress fxids, xmin <= xip[i] < xmax: */
+ FullTransactionId xip[FLEXIBLE_ARRAY_MEMBER];
+} pg_snapshot;
- state->last_xid = XidFromFullTransactionId(fullXid);
- state->epoch = EpochFromFullTransactionId(fullXid);
-}
+#define PG_SNAPSHOT_SIZE(nxip) \
+ (offsetof(pg_snapshot, xip) + sizeof(FullTransactionId) * (nxip))
+#define PG_SNAPSHOT_MAX_NXIP \
+ ((MaxAllocSize - offsetof(pg_snapshot, xip)) / sizeof(FullTransactionId))
/*
* Helper to get a TransactionId from a 64-bit xid with wraparound detection.
@@ -111,10 +87,10 @@ load_xid_epoch(TxidEpoch *state)
* relating to those XIDs.
*/
static bool
-TransactionIdInRecentPast(uint64 xid_with_epoch, TransactionId *extracted_xid)
+TransactionIdInRecentPast(FullTransactionId fxid, TransactionId *extracted_xid)
{
- uint32 xid_epoch = (uint32) (xid_with_epoch >> 32);
- TransactionId xid = (TransactionId) xid_with_epoch;
+ uint32 xid_epoch = EpochFromFullTransactionId(fxid);
+ TransactionId xid = XidFromFullTransactionId(fxid);
uint32 now_epoch;
TransactionId now_epoch_next_xid;
FullTransactionId now_fullxid;
@@ -134,11 +110,12 @@ TransactionIdInRecentPast(uint64 xid_with_epoch, TransactionId *extracted_xid)
return true;
/* If the transaction ID is in the future, throw an error. */
- if (xid_with_epoch >= U64FromFullTransactionId(now_fullxid))
+ if (!FullTransactionIdPrecedes(fxid, now_fullxid))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("transaction ID %s is in the future",
- psprintf(UINT64_FORMAT, xid_with_epoch))));
+ psprintf(UINT64_FORMAT,
+ U64FromFullTransactionId(fxid)))));
/*
* ShmemVariableCache->oldestClogXid is protected by CLogTruncationLock,
@@ -164,41 +141,46 @@ TransactionIdInRecentPast(uint64 xid_with_epoch, TransactionId *extracted_xid)
}
/*
- * do a TransactionId -> txid conversion for an XID near the given epoch
+ * Convert a TransactionId obtained from a snapshot held by the caller to a
+ * FullTransactionId. Use next_fxid as a reference FullTransactionId, so that
+ * we can compute the high order bits. It must have been obtained by the
+ * caller with ReadNextFullTransactionId() after the snapshot was created.
*/
-static txid
-convert_xid(TransactionId xid, const TxidEpoch *state)
+static FullTransactionId
+widen_snapshot_xid(TransactionId xid, FullTransactionId next_fxid)
{
- uint64 epoch;
+ TransactionId next_xid = XidFromFullTransactionId(next_fxid);
+ uint32 epoch = EpochFromFullTransactionId(next_fxid);
- /* return special xid's as-is */
+ /* Special transaction ID. */
if (!TransactionIdIsNormal(xid))
- return (txid) xid;
+ return FullTransactionIdFromEpochAndXid(0, xid);
- /* xid can be on either side when near wrap-around */
- epoch = (uint64) state->epoch;
- if (xid > state->last_xid &&
- TransactionIdPrecedes(xid, state->last_xid))
+ /*
+ * The 64 bit result must be <= next_fxid, since next_fxid hadn't been
+ * issued yet when the snapshot was created. Every TransactionId in the
+ * snapshot must therefore be from the same epoch as next_fxid, or the
+ * epoch before. We know this because next_fxid is never allow to get
+ * more than one epoch ahead of the TransactionIds in any snapshot.
+ */
+ if (xid > next_xid)
epoch--;
- else if (xid < state->last_xid &&
- TransactionIdFollows(xid, state->last_xid))
- epoch++;
- return (epoch << 32) | xid;
+ return FullTransactionIdFromEpochAndXid(epoch, xid);
}
/*
* txid comparator for qsort/bsearch
*/
static int
-cmp_txid(const void *aa, const void *bb)
+cmp_fxid(const void *aa, const void *bb)
{
- txid a = *(const txid *) aa;
- txid b = *(const txid *) bb;
+ FullTransactionId a = *(const FullTransactionId *) aa;
+ FullTransactionId b = *(const FullTransactionId *) bb;
- if (a < b)
+ if (FullTransactionIdPrecedes(a, b))
return -1;
- if (a > b)
+ if (FullTransactionIdPrecedes(b, a))
return 1;
return 0;
}
@@ -211,31 +193,33 @@ cmp_txid(const void *aa, const void *bb)
* will not be used.
*/
static void
-sort_snapshot(TxidSnapshot *snap)
+sort_snapshot(pg_snapshot *snap)
{
if (snap->nxip > 1)
{
- qsort(snap->xip, snap->nxip, sizeof(txid), cmp_txid);
- snap->nxip = qunique(snap->xip, snap->nxip, sizeof(txid), cmp_txid);
+ qsort(snap->xip, snap->nxip, sizeof(FullTransactionId), cmp_fxid);
+ snap->nxip = qunique(snap->xip, snap->nxip, sizeof(FullTransactionId),
+ cmp_fxid);
}
}
/*
- * check txid visibility.
+ * check fxid visibility.
*/
static bool
-is_visible_txid(txid value, const TxidSnapshot *snap)
+is_visible_fxid(FullTransactionId value, const pg_snapshot *snap)
{
- if (value < snap->xmin)
+ if (FullTransactionIdPrecedes(value, snap->xmin))
return true;
- else if (value >= snap->xmax)
+ else if (!FullTransactionIdPrecedes(value, snap->xmax))
return false;
#ifdef USE_BSEARCH_IF_NXIP_GREATER
else if (snap->nxip > USE_BSEARCH_IF_NXIP_GREATER)
{
void *res;
- res = bsearch(&value, snap->xip, snap->nxip, sizeof(txid), cmp_txid);
+ res = bsearch(&value, snap->xip, snap->nxip, sizeof(FullTransactionId),
+ cmp_fxid);
/* if found, transaction is still in progress */
return (res) ? false : true;
}
@@ -246,7 +230,7 @@ is_visible_txid(txid value, const TxidSnapshot *snap)
for (i = 0; i < snap->nxip; i++)
{
- if (value == snap->xip[i])
+ if (FullTransactionIdEquals(value, snap->xip[i]))
return false;
}
return true;
@@ -254,13 +238,13 @@ is_visible_txid(txid value, const TxidSnapshot *snap)
}
/*
- * helper functions to use StringInfo for TxidSnapshot creation.
+ * helper functions to use StringInfo for pg_snapshot creation.
*/
static StringInfo
-buf_init(txid xmin, txid xmax)
+buf_init(FullTransactionId xmin, FullTransactionId xmax)
{
- TxidSnapshot snap;
+ pg_snapshot snap;
StringInfo buf;
snap.xmin = xmin;
@@ -268,25 +252,25 @@ buf_init(txid xmin, txid xmax)
snap.nxip = 0;
buf = makeStringInfo();
- appendBinaryStringInfo(buf, (char *) &snap, TXID_SNAPSHOT_SIZE(0));
+ appendBinaryStringInfo(buf, (char *) &snap, PG_SNAPSHOT_SIZE(0));
return buf;
}
static void
-buf_add_txid(StringInfo buf, txid xid)
+buf_add_txid(StringInfo buf, FullTransactionId fxid)
{
- TxidSnapshot *snap = (TxidSnapshot *) buf->data;
+ pg_snapshot *snap = (pg_snapshot *) buf->data;
/* do this before possible realloc */
snap->nxip++;
- appendBinaryStringInfo(buf, (char *) &xid, sizeof(xid));
+ appendBinaryStringInfo(buf, (char *) &fxid, sizeof(fxid));
}
-static TxidSnapshot *
+static pg_snapshot *
buf_finalize(StringInfo buf)
{
- TxidSnapshot *snap = (TxidSnapshot *) buf->data;
+ pg_snapshot *snap = (pg_snapshot *) buf->data;
SET_VARSIZE(snap, buf->len);
@@ -298,67 +282,33 @@ buf_finalize(StringInfo buf)
}
/*
- * simple number parser.
- *
- * We return 0 on error, which is invalid value for txid.
- */
-static txid
-str2txid(const char *s, const char **endp)
-{
- txid val = 0;
- txid cutoff = MAX_TXID / 10;
- txid cutlim = MAX_TXID % 10;
-
- for (; *s; s++)
- {
- unsigned d;
-
- if (*s < '0' || *s > '9')
- break;
- d = *s - '0';
-
- /*
- * check for overflow
- */
- if (val > cutoff || (val == cutoff && d > cutlim))
- {
- val = 0;
- break;
- }
-
- val = val * 10 + d;
- }
- if (endp)
- *endp = s;
- return val;
-}
-
-/*
* parse snapshot from cstring
*/
-static TxidSnapshot *
+static pg_snapshot *
parse_snapshot(const char *str)
{
- txid xmin;
- txid xmax;
- txid last_val = 0,
- val;
+ FullTransactionId xmin;
+ FullTransactionId xmax;
+ FullTransactionId last_val = InvalidFullTransactionId;
+ FullTransactionId val;
const char *str_start = str;
- const char *endp;
+ char *endp;
StringInfo buf;
- xmin = str2txid(str, &endp);
+ xmin = FullTransactionIdFromU64(pg_strtouint64(str, &endp, 10));
if (*endp != ':')
goto bad_format;
str = endp + 1;
- xmax = str2txid(str, &endp);
+ xmax = FullTransactionIdFromU64(pg_strtouint64(str, &endp, 10));
if (*endp != ':')
goto bad_format;
str = endp + 1;
/* it should look sane */
- if (xmin == 0 || xmax == 0 || xmin > xmax)
+ if (!FullTransactionIdIsValid(xmin) ||
+ !FullTransactionIdIsValid(xmax) ||
+ FullTransactionIdPrecedes(xmax, xmin))
goto bad_format;
/* allocate buffer */
@@ -368,15 +318,17 @@ parse_snapshot(const char *str)
while (*str != '\0')
{
/* read next value */
- val = str2txid(str, &endp);
+ val = FullTransactionIdFromU64(pg_strtouint64(str, &endp, 10));
str = endp;
/* require the input to be in order */
- if (val < xmin || val >= xmax || val < last_val)
+ if (FullTransactionIdPrecedes(val, xmin) ||
+ FullTransactionIdFollowsOrEquals(val, xmax) ||
+ FullTransactionIdPrecedes(val, last_val))
goto bad_format;
/* skip duplicates */
- if (val != last_val)
+ if (!FullTransactionIdEquals(val, last_val))
buf_add_txid(buf, val);
last_val = val;
@@ -392,108 +344,82 @@ bad_format:
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type %s: \"%s\"",
- "txid_snapshot", str_start)));
+ "pg_snapshot", str_start)));
return NULL; /* keep compiler quiet */
}
/*
- * Public functions.
- *
- * txid_current() and txid_current_snapshot() are the only ones that
- * communicate with core xid machinery. All the others work on data
- * returned by them.
- */
-
-/*
- * txid_current() returns int8
+ * pg_current_xact_id() returns xid8
*
- * Return the current toplevel transaction ID as TXID
+ * Return the current toplevel full transaction ID.
* If the current transaction does not have one, one is assigned.
- *
- * This value has the epoch as the high 32 bits and the 32-bit xid
- * as the low 32 bits.
*/
Datum
-txid_current(PG_FUNCTION_ARGS)
+pg_current_xact_id(PG_FUNCTION_ARGS)
{
- txid val;
- TxidEpoch state;
-
/*
* Must prevent during recovery because if an xid is not assigned we try
* to assign one, which would fail. Programs already rely on this function
* to always return a valid current xid, so we should not change this to
* return NULL or similar invalid xid.
*/
- PreventCommandDuringRecovery("txid_current()");
-
- load_xid_epoch(&state);
+ PreventCommandDuringRecovery("pg_current_xact_id()");
- val = convert_xid(GetTopTransactionId(), &state);
-
- PG_RETURN_INT64(val);
+ PG_RETURN_FULLTRANSACTIONID(GetTopFullTransactionId());
}
/*
- * Same as txid_current() but doesn't assign a new xid if there isn't one
- * yet.
+ * Same as pg_current_xact_if_assigned() but doesn't assign a new xid if there
+ * isn't one yet.
*/
Datum
-txid_current_if_assigned(PG_FUNCTION_ARGS)
+pg_current_xact_id_if_assigned(PG_FUNCTION_ARGS)
{
- txid val;
- TxidEpoch state;
- TransactionId topxid = GetTopTransactionIdIfAny();
+ FullTransactionId topfxid = GetTopFullTransactionIdIfAny();
- if (topxid == InvalidTransactionId)
+ if (!FullTransactionIdIsValid(topfxid))
PG_RETURN_NULL();
- load_xid_epoch(&state);
-
- val = convert_xid(topxid, &state);
-
- PG_RETURN_INT64(val);
+ PG_RETURN_FULLTRANSACTIONID(topfxid);
}
/*
- * txid_current_snapshot() returns txid_snapshot
+ * pg_current_snapshot() returns pg_snapshot
*
- * Return current snapshot in TXID format
+ * Return current snapshot
*
* Note that only top-transaction XIDs are included in the snapshot.
*/
Datum
-txid_current_snapshot(PG_FUNCTION_ARGS)
+pg_current_snapshot(PG_FUNCTION_ARGS)
{
- TxidSnapshot *snap;
+ pg_snapshot *snap;
uint32 nxip,
i;
- TxidEpoch state;
Snapshot cur;
+ FullTransactionId next_fxid = ReadNextFullTransactionId();
cur = GetActiveSnapshot();
if (cur == NULL)
elog(ERROR, "no active snapshot set");
- load_xid_epoch(&state);
-
/*
* Compile-time limits on the procarray (MAX_BACKENDS processes plus
* MAX_BACKENDS prepared transactions) guarantee nxip won't be too large.
*/
- StaticAssertStmt(MAX_BACKENDS * 2 <= TXID_SNAPSHOT_MAX_NXIP,
- "possible overflow in txid_current_snapshot()");
+ StaticAssertStmt(MAX_BACKENDS * 2 <= PG_SNAPSHOT_MAX_NXIP,
+ "possible overflow in pg_current_snapshot()");
/* allocate */
nxip = cur->xcnt;
- snap = palloc(TXID_SNAPSHOT_SIZE(nxip));
+ snap = palloc(PG_SNAPSHOT_SIZE(nxip));
/* fill */
- snap->xmin = convert_xid(cur->xmin, &state);
- snap->xmax = convert_xid(cur->xmax, &state);
+ snap->xmin = widen_snapshot_xid(cur->xmin, next_fxid);
+ snap->xmax = widen_snapshot_xid(cur->xmax, next_fxid);
snap->nxip = nxip;
for (i = 0; i < nxip; i++)
- snap->xip[i] = convert_xid(cur->xip[i], &state);
+ snap->xip[i] = widen_snapshot_xid(cur->xip[i], next_fxid);
/*
* We want them guaranteed to be in ascending order. This also removes
@@ -505,21 +431,21 @@ txid_current_snapshot(PG_FUNCTION_ARGS)
sort_snapshot(snap);
/* set size after sorting, because it may have removed duplicate xips */
- SET_VARSIZE(snap, TXID_SNAPSHOT_SIZE(snap->nxip));
+ SET_VARSIZE(snap, PG_SNAPSHOT_SIZE(snap->nxip));
PG_RETURN_POINTER(snap);
}
/*
- * txid_snapshot_in(cstring) returns txid_snapshot
+ * pg_snapshot_in(cstring) returns pg_snapshot
*
- * input function for type txid_snapshot
+ * input function for type pg_snapshot
*/
Datum
-txid_snapshot_in(PG_FUNCTION_ARGS)
+pg_snapshot_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
- TxidSnapshot *snap;
+ pg_snapshot *snap;
snap = parse_snapshot(str);
@@ -527,73 +453,81 @@ txid_snapshot_in(PG_FUNCTION_ARGS)
}
/*
- * txid_snapshot_out(txid_snapshot) returns cstring
+ * pg_snapshot_out(pg_snapshot) returns cstring
*
- * output function for type txid_snapshot
+ * output function for type pg_snapshot
*/
Datum
-txid_snapshot_out(PG_FUNCTION_ARGS)
+pg_snapshot_out(PG_FUNCTION_ARGS)
{
- TxidSnapshot *snap = (TxidSnapshot *) PG_GETARG_VARLENA_P(0);
+ pg_snapshot *snap = (pg_snapshot *) PG_GETARG_VARLENA_P(0);
StringInfoData str;
uint32 i;
initStringInfo(&str);
- appendStringInfo(&str, TXID_FMT ":", snap->xmin);
- appendStringInfo(&str, TXID_FMT ":", snap->xmax);
+ appendStringInfo(&str, UINT64_FORMAT ":",
+ U64FromFullTransactionId(snap->xmin));
+ appendStringInfo(&str, UINT64_FORMAT ":",
+ U64FromFullTransactionId(snap->xmax));
for (i = 0; i < snap->nxip; i++)
{
if (i > 0)
appendStringInfoChar(&str, ',');
- appendStringInfo(&str, TXID_FMT, snap->xip[i]);
+ appendStringInfo(&str, UINT64_FORMAT,
+ U64FromFullTransactionId(snap->xip[i]));
}
PG_RETURN_CSTRING(str.data);
}
/*
- * txid_snapshot_recv(internal) returns txid_snapshot
+ * pg_snapshot_recv(internal) returns pg_snapshot
*
- * binary input function for type txid_snapshot
+ * binary input function for type pg_snapshot
*
* format: int4 nxip, int8 xmin, int8 xmax, int8 xip
*/
Datum
-txid_snapshot_recv(PG_FUNCTION_ARGS)
+pg_snapshot_recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
- TxidSnapshot *snap;
- txid last = 0;
+ pg_snapshot *snap;
+ FullTransactionId last = InvalidFullTransactionId;
int nxip;
int i;
- txid xmin,
- xmax;
+ FullTransactionId xmin;
+ FullTransactionId xmax;
/* load and validate nxip */
nxip = pq_getmsgint(buf, 4);
- if (nxip < 0 || nxip > TXID_SNAPSHOT_MAX_NXIP)
+ if (nxip < 0 || nxip > PG_SNAPSHOT_MAX_NXIP)
goto bad_format;
- xmin = pq_getmsgint64(buf);
- xmax = pq_getmsgint64(buf);
- if (xmin == 0 || xmax == 0 || xmin > xmax || xmax > MAX_TXID)
+ xmin = FullTransactionIdFromU64((uint64) pq_getmsgint64(buf));
+ xmax = FullTransactionIdFromU64((uint64) pq_getmsgint64(buf));
+ if (!FullTransactionIdIsValid(xmin) ||
+ !FullTransactionIdIsValid(xmax) ||
+ FullTransactionIdPrecedes(xmax, xmin))
goto bad_format;
- snap = palloc(TXID_SNAPSHOT_SIZE(nxip));
+ snap = palloc(PG_SNAPSHOT_SIZE(nxip));
snap->xmin = xmin;
snap->xmax = xmax;
for (i = 0; i < nxip; i++)
{
- txid cur = pq_getmsgint64(buf);
+ FullTransactionId cur =
+ FullTransactionIdFromU64((uint64) pq_getmsgint64(buf));
- if (cur < last || cur < xmin || cur >= xmax)
+ if (FullTransactionIdPrecedes(cur, last) ||
+ FullTransactionIdPrecedes(cur, xmin) ||
+ FullTransactionIdPrecedes(xmax, cur))
goto bad_format;
/* skip duplicate xips */
- if (cur == last)
+ if (FullTransactionIdEquals(cur, last))
{
i--;
nxip--;
@@ -604,95 +538,95 @@ txid_snapshot_recv(PG_FUNCTION_ARGS)
last = cur;
}
snap->nxip = nxip;
- SET_VARSIZE(snap, TXID_SNAPSHOT_SIZE(nxip));
+ SET_VARSIZE(snap, PG_SNAPSHOT_SIZE(nxip));
PG_RETURN_POINTER(snap);
bad_format:
ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
- errmsg("invalid external txid_snapshot data")));
+ errmsg("invalid external pg_snapshot data")));
PG_RETURN_POINTER(NULL); /* keep compiler quiet */
}
/*
- * txid_snapshot_send(txid_snapshot) returns bytea
+ * pg_snapshot_send(pg_snapshot) returns bytea
*
- * binary output function for type txid_snapshot
+ * binary output function for type pg_snapshot
*
- * format: int4 nxip, int8 xmin, int8 xmax, int8 xip
+ * format: int4 nxip, u64 xmin, u64 xmax, u64 xip...
*/
Datum
-txid_snapshot_send(PG_FUNCTION_ARGS)
+pg_snapshot_send(PG_FUNCTION_ARGS)
{
- TxidSnapshot *snap = (TxidSnapshot *) PG_GETARG_VARLENA_P(0);
+ pg_snapshot *snap = (pg_snapshot *) PG_GETARG_VARLENA_P(0);
StringInfoData buf;
uint32 i;
pq_begintypsend(&buf);
pq_sendint32(&buf, snap->nxip);
- pq_sendint64(&buf, snap->xmin);
- pq_sendint64(&buf, snap->xmax);
+ pq_sendint64(&buf, (int64) U64FromFullTransactionId(snap->xmin));
+ pq_sendint64(&buf, (int64) U64FromFullTransactionId(snap->xmax));
for (i = 0; i < snap->nxip; i++)
- pq_sendint64(&buf, snap->xip[i]);
+ pq_sendint64(&buf, (int64) U64FromFullTransactionId(snap->xip[i]));
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/*
- * txid_visible_in_snapshot(int8, txid_snapshot) returns bool
+ * pg_visible_in_snapshot(xid8, pg_snapshot) returns bool
*
* is txid visible in snapshot ?
*/
Datum
-txid_visible_in_snapshot(PG_FUNCTION_ARGS)
+pg_visible_in_snapshot(PG_FUNCTION_ARGS)
{
- txid value = PG_GETARG_INT64(0);
- TxidSnapshot *snap = (TxidSnapshot *) PG_GETARG_VARLENA_P(1);
+ FullTransactionId value = PG_GETARG_FULLTRANSACTIONID(0);
+ pg_snapshot *snap = (pg_snapshot *) PG_GETARG_VARLENA_P(1);
- PG_RETURN_BOOL(is_visible_txid(value, snap));
+ PG_RETURN_BOOL(is_visible_fxid(value, snap));
}
/*
- * txid_snapshot_xmin(txid_snapshot) returns int8
+ * pg_snapshot_xmin(pg_snapshot) returns xid8
*
* return snapshot's xmin
*/
Datum
-txid_snapshot_xmin(PG_FUNCTION_ARGS)
+pg_snapshot_xmin(PG_FUNCTION_ARGS)
{
- TxidSnapshot *snap = (TxidSnapshot *) PG_GETARG_VARLENA_P(0);
+ pg_snapshot *snap = (pg_snapshot *) PG_GETARG_VARLENA_P(0);
- PG_RETURN_INT64(snap->xmin);
+ PG_RETURN_FULLTRANSACTIONID(snap->xmin);
}
/*
- * txid_snapshot_xmax(txid_snapshot) returns int8
+ * pg_snapshot_xmax(pg_snapshot) returns xid8
*
* return snapshot's xmax
*/
Datum
-txid_snapshot_xmax(PG_FUNCTION_ARGS)
+pg_snapshot_xmax(PG_FUNCTION_ARGS)
{
- TxidSnapshot *snap = (TxidSnapshot *) PG_GETARG_VARLENA_P(0);
+ pg_snapshot *snap = (pg_snapshot *) PG_GETARG_VARLENA_P(0);
- PG_RETURN_INT64(snap->xmax);
+ PG_RETURN_FULLTRANSACTIONID(snap->xmax);
}
/*
- * txid_snapshot_xip(txid_snapshot) returns setof int8
+ * pg_snapshot_xip(pg_snapshot) returns setof xid8
*
- * return in-progress TXIDs in snapshot.
+ * return in-progress xid8s in snapshot.
*/
Datum
-txid_snapshot_xip(PG_FUNCTION_ARGS)
+pg_snapshot_xip(PG_FUNCTION_ARGS)
{
FuncCallContext *fctx;
- TxidSnapshot *snap;
- txid value;
+ pg_snapshot *snap;
+ FullTransactionId value;
/* on first call initialize fctx and get copy of snapshot */
if (SRF_IS_FIRSTCALL())
{
- TxidSnapshot *arg = (TxidSnapshot *) PG_GETARG_VARLENA_P(0);
+ pg_snapshot *arg = (pg_snapshot *) PG_GETARG_VARLENA_P(0);
fctx = SRF_FIRSTCALL_INIT();
@@ -709,7 +643,7 @@ txid_snapshot_xip(PG_FUNCTION_ARGS)
if (fctx->call_cntr < snap->nxip)
{
value = snap->xip[fctx->call_cntr];
- SRF_RETURN_NEXT(fctx, Int64GetDatum(value));
+ SRF_RETURN_NEXT(fctx, FullTransactionIdGetDatum(value));
}
else
{
@@ -728,10 +662,10 @@ txid_snapshot_xip(PG_FUNCTION_ARGS)
* though the parent xact may still be in progress or may have aborted.
*/
Datum
-txid_status(PG_FUNCTION_ARGS)
+pg_xact_status(PG_FUNCTION_ARGS)
{
const char *status;
- uint64 xid_with_epoch = PG_GETARG_INT64(0);
+ FullTransactionId fxid = PG_GETARG_FULLTRANSACTIONID(0);
TransactionId xid;
/*
@@ -739,7 +673,7 @@ txid_status(PG_FUNCTION_ARGS)
* an I/O error on SLRU lookup.
*/
LWLockAcquire(CLogTruncationLock, LW_SHARED);
- if (TransactionIdInRecentPast(xid_with_epoch, &xid))
+ if (TransactionIdInRecentPast(fxid, &xid))
{
Assert(TransactionIdIsValid(xid));
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 4201790ec48..498992ff84c 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202004061
+#define CATALOG_VERSION_NO 202004062
#endif
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6be7e4f1571..2d1862a9d8a 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -9505,46 +9505,89 @@
proname => 'jsonb_path_match_opr', prorettype => 'bool',
proargtypes => 'jsonb jsonpath', prosrc => 'jsonb_path_match_opr' },
-# txid
+# historical int8/txid_snapshot variants of xid8 functions
{ oid => '2939', descr => 'I/O',
proname => 'txid_snapshot_in', prorettype => 'txid_snapshot',
- proargtypes => 'cstring', prosrc => 'txid_snapshot_in' },
+ proargtypes => 'cstring', prosrc => 'pg_snapshot_in' },
{ oid => '2940', descr => 'I/O',
proname => 'txid_snapshot_out', prorettype => 'cstring',
- proargtypes => 'txid_snapshot', prosrc => 'txid_snapshot_out' },
+ proargtypes => 'txid_snapshot', prosrc => 'pg_snapshot_out' },
{ oid => '2941', descr => 'I/O',
proname => 'txid_snapshot_recv', prorettype => 'txid_snapshot',
- proargtypes => 'internal', prosrc => 'txid_snapshot_recv' },
+ proargtypes => 'internal', prosrc => 'pg_snapshot_recv' },
{ oid => '2942', descr => 'I/O',
proname => 'txid_snapshot_send', prorettype => 'bytea',
- proargtypes => 'txid_snapshot', prosrc => 'txid_snapshot_send' },
+ proargtypes => 'txid_snapshot', prosrc => 'pg_snapshot_send' },
{ oid => '2943', descr => 'get current transaction ID',
proname => 'txid_current', provolatile => 's', proparallel => 'u',
- prorettype => 'int8', proargtypes => '', prosrc => 'txid_current' },
+ prorettype => 'int8', proargtypes => '', prosrc => 'pg_current_xact_id' },
{ oid => '3348', descr => 'get current transaction ID',
proname => 'txid_current_if_assigned', provolatile => 's', proparallel => 'u',
prorettype => 'int8', proargtypes => '',
- prosrc => 'txid_current_if_assigned' },
+ prosrc => 'pg_current_xact_id_if_assigned' },
{ oid => '2944', descr => 'get current snapshot',
proname => 'txid_current_snapshot', provolatile => 's',
prorettype => 'txid_snapshot', proargtypes => '',
- prosrc => 'txid_current_snapshot' },
+ prosrc => 'pg_current_snapshot' },
{ oid => '2945', descr => 'get xmin of snapshot',
proname => 'txid_snapshot_xmin', prorettype => 'int8',
- proargtypes => 'txid_snapshot', prosrc => 'txid_snapshot_xmin' },
+ proargtypes => 'txid_snapshot', prosrc => 'pg_snapshot_xmin' },
{ oid => '2946', descr => 'get xmax of snapshot',
proname => 'txid_snapshot_xmax', prorettype => 'int8',
- proargtypes => 'txid_snapshot', prosrc => 'txid_snapshot_xmax' },
+ proargtypes => 'txid_snapshot', prosrc => 'pg_snapshot_xmax' },
{ oid => '2947', descr => 'get set of in-progress txids in snapshot',
proname => 'txid_snapshot_xip', prorows => '50', proretset => 't',
prorettype => 'int8', proargtypes => 'txid_snapshot',
- prosrc => 'txid_snapshot_xip' },
+ prosrc => 'pg_snapshot_xip' },
{ oid => '2948', descr => 'is txid visible in snapshot?',
proname => 'txid_visible_in_snapshot', prorettype => 'bool',
- proargtypes => 'int8 txid_snapshot', prosrc => 'txid_visible_in_snapshot' },
+ proargtypes => 'int8 txid_snapshot', prosrc => 'pg_visible_in_snapshot' },
{ oid => '3360', descr => 'commit status of transaction',
proname => 'txid_status', provolatile => 'v', prorettype => 'text',
- proargtypes => 'int8', prosrc => 'txid_status' },
+ proargtypes => 'int8', prosrc => 'pg_xact_status' },
+
+# pg_snapshot functions
+{ oid => '9247', descr => 'I/O',
+ proname => 'pg_snapshot_in', prorettype => 'pg_snapshot',
+ proargtypes => 'cstring', prosrc => 'pg_snapshot_in' },
+{ oid => '9248', descr => 'I/O',
+ proname => 'pg_snapshot_out', prorettype => 'cstring',
+ proargtypes => 'pg_snapshot', prosrc => 'pg_snapshot_out' },
+{ oid => '9249', descr => 'I/O',
+ proname => 'pg_snapshot_recv', prorettype => 'pg_snapshot',
+ proargtypes => 'internal', prosrc => 'pg_snapshot_recv' },
+{ oid => '9250', descr => 'I/O',
+ proname => 'pg_snapshot_send', prorettype => 'bytea',
+ proargtypes => 'pg_snapshot', prosrc => 'pg_snapshot_send' },
+{ oid => '9253', descr => 'get current snapshot',
+ proname => 'pg_current_snapshot', provolatile => 's',
+ prorettype => 'pg_snapshot', proargtypes => '',
+ prosrc => 'pg_current_snapshot' },
+{ oid => '9254', descr => 'get xmin of snapshot',
+ proname => 'pg_snapshot_xmin', prorettype => 'xid8',
+ proargtypes => 'pg_snapshot', prosrc => 'pg_snapshot_xmin' },
+{ oid => '9255', descr => 'get xmax of snapshot',
+ proname => 'pg_snapshot_xmax', prorettype => 'xid8',
+ proargtypes => 'pg_snapshot', prosrc => 'pg_snapshot_xmax' },
+{ oid => '9256', descr => 'get set of in-progress transactions in snapshot',
+ proname => 'pg_snapshot_xip', prorows => '50', proretset => 't',
+ prorettype => 'xid8', proargtypes => 'pg_snapshot',
+ prosrc => 'pg_snapshot_xip' },
+{ oid => '9257', descr => 'is xid8 visible in snapshot?',
+ proname => 'pg_visible_in_snapshot', prorettype => 'bool',
+ proargtypes => 'xid8 pg_snapshot', prosrc => 'pg_visible_in_snapshot' },
+
+# transaction ID and status functions
+{ oid => '9251', descr => 'get current transaction ID',
+ proname => 'pg_current_xact_id', provolatile => 's', proparallel => 'u',
+ prorettype => 'xid8', proargtypes => '', prosrc => 'pg_current_xact_id' },
+{ oid => '9252', descr => 'get current transaction ID',
+ proname => 'pg_current_xact_id_if_assigned', provolatile => 's', proparallel => 'u',
+ prorettype => 'xid8', proargtypes => '',
+ prosrc => 'pg_current_xact_id_if_assigned' },
+{ oid => '9258', descr => 'commit status of transaction',
+ proname => 'pg_xact_status', provolatile => 'v', prorettype => 'text',
+ proargtypes => 'xid8', prosrc => 'pg_xact_status' },
# record comparison using normal comparison rules
{ oid => '2981',
diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat
index a1f441b8daa..78f44af5e75 100644
--- a/src/include/catalog/pg_type.dat
+++ b/src/include/catalog/pg_type.dat
@@ -460,6 +460,11 @@
typcategory => 'U', typinput => 'txid_snapshot_in',
typoutput => 'txid_snapshot_out', typreceive => 'txid_snapshot_recv',
typsend => 'txid_snapshot_send', typalign => 'd', typstorage => 'x' },
+{ oid => '8355', array_type_oid => '8356', descr => 'snapshot',
+ typname => 'pg_snapshot', typlen => '-1', typbyval => 'f',
+ typcategory => 'U', typinput => 'pg_snapshot_in',
+ typoutput => 'pg_snapshot_out', typreceive => 'pg_snapshot_recv',
+ typsend => 'pg_snapshot_send', typalign => 'd', typstorage => 'x' },
# range types
{ oid => '3904', array_type_oid => '3905', descr => 'range of integers',
diff --git a/src/test/modules/commit_ts/t/004_restart.pl b/src/test/modules/commit_ts/t/004_restart.pl
index bd4b9433056..39ca25a06bf 100644
--- a/src/test/modules/commit_ts/t/004_restart.pl
+++ b/src/test/modules/commit_ts/t/004_restart.pl
@@ -45,7 +45,7 @@ my $xid = $node_master->safe_psql(
'postgres', qq[
BEGIN;
INSERT INTO committs_test(x, y) VALUES (1, current_timestamp);
- SELECT txid_current();
+ SELECT pg_current_xact_id()::xid;
COMMIT;
]);
@@ -93,7 +93,7 @@ DECLARE
i int;
BEGIN
FOR i in 1..cnt LOOP
- EXECUTE 'SELECT txid_current()';
+ EXECUTE 'SELECT pg_current_xact_id()';
COMMIT;
END LOOP;
END;
@@ -115,7 +115,7 @@ my $xid_disabled = $node_master->safe_psql(
'postgres', qq[
BEGIN;
INSERT INTO committs_test(x, y) VALUES (2, current_timestamp);
- SELECT txid_current();
+ SELECT pg_current_xact_id();
COMMIT;
]);
diff --git a/src/test/modules/test_ddl_deparse/expected/create_table.out b/src/test/modules/test_ddl_deparse/expected/create_table.out
index 523c9960933..c7c9bf8971f 100644
--- a/src/test/modules/test_ddl_deparse/expected/create_table.out
+++ b/src/test/modules/test_ddl_deparse/expected/create_table.out
@@ -43,7 +43,7 @@ CREATE TABLE datatype_table (
v_json JSON,
v_xml XML,
v_uuid UUID,
- v_txid_snapshot txid_snapshot,
+ v_pg_snapshot pg_snapshot,
v_enum ENUM_TEST,
v_postal_code japanese_postal_code,
v_int2range int2range,
diff --git a/src/test/modules/test_ddl_deparse/sql/create_table.sql b/src/test/modules/test_ddl_deparse/sql/create_table.sql
index dd3a908638d..39cdb9df03c 100644
--- a/src/test/modules/test_ddl_deparse/sql/create_table.sql
+++ b/src/test/modules/test_ddl_deparse/sql/create_table.sql
@@ -44,7 +44,7 @@ CREATE TABLE datatype_table (
v_json JSON,
v_xml XML,
v_uuid UUID,
- v_txid_snapshot txid_snapshot,
+ v_pg_snapshot pg_snapshot,
v_enum ENUM_TEST,
v_postal_code japanese_postal_code,
v_int2range int2range,
diff --git a/src/test/recovery/t/003_recovery_targets.pl b/src/test/recovery/t/003_recovery_targets.pl
index fd14bab208b..2a520e6db1a 100644
--- a/src/test/recovery/t/003_recovery_targets.pl
+++ b/src/test/recovery/t/003_recovery_targets.pl
@@ -68,7 +68,7 @@ $node_master->backup('my_backup');
$node_master->safe_psql('postgres',
"INSERT INTO tab_int VALUES (generate_series(1001,2000))");
my $ret = $node_master->safe_psql('postgres',
- "SELECT pg_current_wal_lsn(), txid_current();");
+ "SELECT pg_current_wal_lsn(), pg_current_xact_id();");
my ($lsn2, $recovery_txid) = split /\|/, $ret;
# More data, with recovery target timestamp
diff --git a/src/test/recovery/t/011_crash_recovery.pl b/src/test/recovery/t/011_crash_recovery.pl
index 526a3481fb5..ca6e92b50df 100644
--- a/src/test/recovery/t/011_crash_recovery.pl
+++ b/src/test/recovery/t/011_crash_recovery.pl
@@ -24,7 +24,7 @@ $node->start;
my ($stdin, $stdout, $stderr) = ('', '', '');
-# Ensure that txid_status reports 'aborted' for xacts
+# Ensure that pg_xact_status reports 'aborted' for xacts
# that were in-progress during crash. To do that, we need
# an xact to be in-progress when we crash and we need to know
# its xid.
@@ -42,7 +42,7 @@ my $tx = IPC::Run::start(
$stdin .= q[
BEGIN;
CREATE TABLE mine(x integer);
-SELECT txid_current();
+SELECT pg_current_xact_id();
];
$tx->pump until $stdout =~ /[[:digit:]]+[\r\n]$/;
@@ -50,7 +50,7 @@ $tx->pump until $stdout =~ /[[:digit:]]+[\r\n]$/;
my $xid = $stdout;
chomp($xid);
-is($node->safe_psql('postgres', qq[SELECT txid_status('$xid');]),
+is($node->safe_psql('postgres', qq[SELECT pg_xact_status('$xid');]),
'in progress', 'own xid is in-progress');
# Crash and restart the postmaster
@@ -58,11 +58,11 @@ $node->stop('immediate');
$node->start;
# Make sure we really got a new xid
-cmp_ok($node->safe_psql('postgres', 'SELECT txid_current()'),
+cmp_ok($node->safe_psql('postgres', 'SELECT pg_current_xact_id()'),
'>', $xid, 'new xid after restart is greater');
# and make sure we show the in-progress xact as aborted
-is($node->safe_psql('postgres', qq[SELECT txid_status('$xid');]),
+is($node->safe_psql('postgres', qq[SELECT pg_xact_status('$xid');]),
'aborted', 'xid is aborted after crash');
$tx->kill_kill;
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index e46775afbf5..f343f9b42ea 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -2556,7 +2556,7 @@ from pg_locks l join pg_class c on l.relation = c.oid
where virtualtransaction = (
select virtualtransaction
from pg_locks
- where transactionid = txid_current()::integer)
+ where transactionid = pg_current_xact_id()::xid)
and locktype = 'relation'
and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog')
and c.relname != 'my_locks'
@@ -2719,7 +2719,7 @@ from pg_locks l join pg_class c on l.relation = c.oid
where virtualtransaction = (
select virtualtransaction
from pg_locks
- where transactionid = txid_current()::integer)
+ where transactionid = pg_current_xact_id()::xid)
and locktype = 'relation'
and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog')
and c.relname = 'my_locks'
diff --git a/src/test/regress/expected/hs_standby_functions.out b/src/test/regress/expected/hs_standby_functions.out
index e0af677ea1b..ce846b758bf 100644
--- a/src/test/regress/expected/hs_standby_functions.out
+++ b/src/test/regress/expected/hs_standby_functions.out
@@ -4,9 +4,9 @@
-- hs_standby_functions.sql
--
-- should fail
-select txid_current();
-ERROR: cannot execute txid_current() during recovery
-select length(txid_current_snapshot()::text) >= 4;
+select pg_current_xact_id();
+ERROR: cannot execute pg_current_xact_id() during recovery
+select length(pg_current_snapshot()::text) >= 4;
?column?
----------
t
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index 0c03afe53d2..8d350ab61bb 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -194,9 +194,11 @@ WHERE p1.oid != p2.oid AND
ORDER BY 1, 2;
prorettype | prorettype
------------+------------
+ 20 | 9419
25 | 1043
1114 | 1184
-(2 rows)
+ 2970 | 8355
+(4 rows)
SELECT DISTINCT p1.proargtypes[0], p2.proargtypes[0]
FROM pg_proc AS p1, pg_proc AS p2
@@ -210,11 +212,13 @@ WHERE p1.oid != p2.oid AND
ORDER BY 1, 2;
proargtypes | proargtypes
-------------+-------------
+ 20 | 9419
25 | 1042
25 | 1043
1114 | 1184
1560 | 1562
-(4 rows)
+ 2970 | 8355
+(6 rows)
SELECT DISTINCT p1.proargtypes[1], p2.proargtypes[1]
FROM pg_proc AS p1, pg_proc AS p2
@@ -231,7 +235,8 @@ ORDER BY 1, 2;
23 | 28
1114 | 1184
1560 | 1562
-(3 rows)
+ 2970 | 8355
+(4 rows)
SELECT DISTINCT p1.proargtypes[2], p2.proargtypes[2]
FROM pg_proc AS p1, pg_proc AS p2
diff --git a/src/test/regress/expected/txid.out b/src/test/regress/expected/txid.out
index 015dae30512..95ba66e95ee 100644
--- a/src/test/regress/expected/txid.out
+++ b/src/test/regress/expected/txid.out
@@ -1,4 +1,7 @@
-- txid_snapshot data type and related functions
+-- Note: these are backward-compatibility functions and types, and have been
+-- replaced by new xid8-based variants. See xid.sql. The txid variants will
+-- be removed in a future release.
-- i/o
select '12:13:'::txid_snapshot;
txid_snapshot
@@ -20,19 +23,19 @@ select '12:16:14,14'::txid_snapshot;
-- errors
select '31:12:'::txid_snapshot;
-ERROR: invalid input syntax for type txid_snapshot: "31:12:"
+ERROR: invalid input syntax for type pg_snapshot: "31:12:"
LINE 1: select '31:12:'::txid_snapshot;
^
select '0:1:'::txid_snapshot;
-ERROR: invalid input syntax for type txid_snapshot: "0:1:"
+ERROR: invalid input syntax for type pg_snapshot: "0:1:"
LINE 1: select '0:1:'::txid_snapshot;
^
select '12:13:0'::txid_snapshot;
-ERROR: invalid input syntax for type txid_snapshot: "12:13:0"
+ERROR: invalid input syntax for type pg_snapshot: "12:13:0"
LINE 1: select '12:13:0'::txid_snapshot;
^
select '12:16:14,13'::txid_snapshot;
-ERROR: invalid input syntax for type txid_snapshot: "12:16:14,13"
+ERROR: invalid input syntax for type pg_snapshot: "12:16:14,13"
LINE 1: select '12:16:14,13'::txid_snapshot;
^
create temp table snapshot_test (
@@ -235,7 +238,7 @@ SELECT txid_snapshot '1:9223372036854775807:3';
(1 row)
SELECT txid_snapshot '1:9223372036854775808:3';
-ERROR: invalid input syntax for type txid_snapshot: "1:9223372036854775808:3"
+ERROR: invalid input syntax for type pg_snapshot: "1:9223372036854775808:3"
LINE 1: SELECT txid_snapshot '1:9223372036854775808:3';
^
-- test txid_current_if_assigned
diff --git a/src/test/regress/expected/update.out b/src/test/regress/expected/update.out
index b7f90de52b1..bf939d79f60 100644
--- a/src/test/regress/expected/update.out
+++ b/src/test/regress/expected/update.out
@@ -230,10 +230,9 @@ INSERT INTO upsert_test VALUES (1, 'Bat') ON CONFLICT(a)
-- ON CONFLICT using system attributes in RETURNING, testing both the
-- inserting and updating paths. See bug report at:
-- https://www.postgresql.org/message-id/73436355-6432-49B1-92ED-1FE4F7E7E100%40finefun.com.au
-CREATE FUNCTION xid_current() RETURNS xid LANGUAGE SQL AS $$SELECT (txid_current() % ((1::int8<<32)))::text::xid;$$;
INSERT INTO upsert_test VALUES (2, 'Beeble') ON CONFLICT(a)
DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a)
- RETURNING tableoid::regclass, xmin = xid_current() AS xmin_correct, xmax = 0 AS xmax_correct;
+ RETURNING tableoid::regclass, xmin = pg_current_xact_id()::xid AS xmin_correct, xmax = 0 AS xmax_correct;
tableoid | xmin_correct | xmax_correct
-------------+--------------+--------------
upsert_test | t | t
@@ -243,13 +242,12 @@ INSERT INTO upsert_test VALUES (2, 'Beeble') ON CONFLICT(a)
-- but it seems worthwhile to have to be explicit if that changes.
INSERT INTO upsert_test VALUES (2, 'Brox') ON CONFLICT(a)
DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a)
- RETURNING tableoid::regclass, xmin = xid_current() AS xmin_correct, xmax = xid_current() AS xmax_correct;
+ RETURNING tableoid::regclass, xmin = pg_current_xact_id()::xid AS xmin_correct, xmax = pg_current_xact_id()::xid AS xmax_correct;
tableoid | xmin_correct | xmax_correct
-------------+--------------+--------------
upsert_test | t | t
(1 row)
-DROP FUNCTION xid_current();
DROP TABLE update_test;
DROP TABLE upsert_test;
---------------------------
diff --git a/src/test/regress/expected/xid.out b/src/test/regress/expected/xid.out
index e9e1fa82591..b7a1ed0f9ee 100644
--- a/src/test/regress/expected/xid.out
+++ b/src/test/regress/expected/xid.out
@@ -134,3 +134,329 @@ create table xid8_t1 (x xid8);
create index on xid8_t1 using btree(x);
create index on xid8_t1 using hash(x);
drop table xid8_t1;
+-- pg_snapshot data type and related functions
+-- Note: another set of tests similar to this exists in txid.sql, for a limited
+-- time (the relevant functions share C code)
+-- i/o
+select '12:13:'::pg_snapshot;
+ pg_snapshot
+-------------
+ 12:13:
+(1 row)
+
+select '12:18:14,16'::pg_snapshot;
+ pg_snapshot
+-------------
+ 12:18:14,16
+(1 row)
+
+select '12:16:14,14'::pg_snapshot;
+ pg_snapshot
+-------------
+ 12:16:14
+(1 row)
+
+-- errors
+select '31:12:'::pg_snapshot;
+ERROR: invalid input syntax for type pg_snapshot: "31:12:"
+LINE 1: select '31:12:'::pg_snapshot;
+ ^
+select '0:1:'::pg_snapshot;
+ERROR: invalid input syntax for type pg_snapshot: "0:1:"
+LINE 1: select '0:1:'::pg_snapshot;
+ ^
+select '12:13:0'::pg_snapshot;
+ERROR: invalid input syntax for type pg_snapshot: "12:13:0"
+LINE 1: select '12:13:0'::pg_snapshot;
+ ^
+select '12:16:14,13'::pg_snapshot;
+ERROR: invalid input syntax for type pg_snapshot: "12:16:14,13"
+LINE 1: select '12:16:14,13'::pg_snapshot;
+ ^
+create temp table snapshot_test (
+ nr integer,
+ snap pg_snapshot
+);
+insert into snapshot_test values (1, '12:13:');
+insert into snapshot_test values (2, '12:20:13,15,18');
+insert into snapshot_test values (3, '100001:100009:100005,100007,100008');
+insert into snapshot_test values (4, '100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131');
+select snap from snapshot_test order by nr;
+ snap
+-------------------------------------------------------------------------------------------------------------------------------------
+ 12:13:
+ 12:20:13,15,18
+ 100001:100009:100005,100007,100008
+ 100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131
+(4 rows)
+
+select pg_snapshot_xmin(snap),
+ pg_snapshot_xmax(snap),
+ pg_snapshot_xip(snap)
+from snapshot_test order by nr;
+ pg_snapshot_xmin | pg_snapshot_xmax | pg_snapshot_xip
+------------------+------------------+-----------------
+ 12 | 20 | 13
+ 12 | 20 | 15
+ 12 | 20 | 18
+ 100001 | 100009 | 100005
+ 100001 | 100009 | 100007
+ 100001 | 100009 | 100008
+ 100 | 150 | 101
+ 100 | 150 | 102
+ 100 | 150 | 103
+ 100 | 150 | 104
+ 100 | 150 | 105
+ 100 | 150 | 106
+ 100 | 150 | 107
+ 100 | 150 | 108
+ 100 | 150 | 109
+ 100 | 150 | 110
+ 100 | 150 | 111
+ 100 | 150 | 112
+ 100 | 150 | 113
+ 100 | 150 | 114
+ 100 | 150 | 115
+ 100 | 150 | 116
+ 100 | 150 | 117
+ 100 | 150 | 118
+ 100 | 150 | 119
+ 100 | 150 | 120
+ 100 | 150 | 121
+ 100 | 150 | 122
+ 100 | 150 | 123
+ 100 | 150 | 124
+ 100 | 150 | 125
+ 100 | 150 | 126
+ 100 | 150 | 127
+ 100 | 150 | 128
+ 100 | 150 | 129
+ 100 | 150 | 130
+ 100 | 150 | 131
+(37 rows)
+
+select id, pg_visible_in_snapshot(id::text::xid8, snap)
+from snapshot_test, generate_series(11, 21) id
+where nr = 2;
+ id | pg_visible_in_snapshot
+----+------------------------
+ 11 | t
+ 12 | t
+ 13 | f
+ 14 | t
+ 15 | f
+ 16 | t
+ 17 | t
+ 18 | f
+ 19 | t
+ 20 | f
+ 21 | f
+(11 rows)
+
+-- test bsearch
+select id, pg_visible_in_snapshot(id::text::xid8, snap)
+from snapshot_test, generate_series(90, 160) id
+where nr = 4;
+ id | pg_visible_in_snapshot
+-----+------------------------
+ 90 | t
+ 91 | t
+ 92 | t
+ 93 | t
+ 94 | t
+ 95 | t
+ 96 | t
+ 97 | t
+ 98 | t
+ 99 | t
+ 100 | t
+ 101 | f
+ 102 | f
+ 103 | f
+ 104 | f
+ 105 | f
+ 106 | f
+ 107 | f
+ 108 | f
+ 109 | f
+ 110 | f
+ 111 | f
+ 112 | f
+ 113 | f
+ 114 | f
+ 115 | f
+ 116 | f
+ 117 | f
+ 118 | f
+ 119 | f
+ 120 | f
+ 121 | f
+ 122 | f
+ 123 | f
+ 124 | f
+ 125 | f
+ 126 | f
+ 127 | f
+ 128 | f
+ 129 | f
+ 130 | f
+ 131 | f
+ 132 | t
+ 133 | t
+ 134 | t
+ 135 | t
+ 136 | t
+ 137 | t
+ 138 | t
+ 139 | t
+ 140 | t
+ 141 | t
+ 142 | t
+ 143 | t
+ 144 | t
+ 145 | t
+ 146 | t
+ 147 | t
+ 148 | t
+ 149 | t
+ 150 | f
+ 151 | f
+ 152 | f
+ 153 | f
+ 154 | f
+ 155 | f
+ 156 | f
+ 157 | f
+ 158 | f
+ 159 | f
+ 160 | f
+(71 rows)
+
+-- test current values also
+select pg_current_xact_id() >= pg_snapshot_xmin(pg_current_snapshot());
+ ?column?
+----------
+ t
+(1 row)
+
+-- we can't assume current is always less than xmax, however
+select pg_visible_in_snapshot(pg_current_xact_id(), pg_current_snapshot());
+ pg_visible_in_snapshot
+------------------------
+ f
+(1 row)
+
+-- test 64bitness
+select pg_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100010001013';
+ pg_snapshot
+---------------------------------------------------------------------
+ 1000100010001000:1000100010001100:1000100010001012,1000100010001013
+(1 row)
+
+select pg_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013');
+ pg_visible_in_snapshot
+------------------------
+ f
+(1 row)
+
+select pg_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013');
+ pg_visible_in_snapshot
+------------------------
+ t
+(1 row)
+
+-- test 64bit overflow
+SELECT pg_snapshot '1:9223372036854775807:3';
+ pg_snapshot
+-------------------------
+ 1:9223372036854775807:3
+(1 row)
+
+SELECT pg_snapshot '1:9223372036854775808:3';
+ERROR: invalid input syntax for type pg_snapshot: "1:9223372036854775808:3"
+LINE 1: SELECT pg_snapshot '1:9223372036854775808:3';
+ ^
+-- test pg_current_xact_id_if_assigned
+BEGIN;
+SELECT pg_current_xact_id_if_assigned() IS NULL;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT pg_current_xact_id() \gset
+SELECT pg_current_xact_id_if_assigned() IS NOT DISTINCT FROM xid8 :'pg_current_xact_id';
+ ?column?
+----------
+ t
+(1 row)
+
+COMMIT;
+-- test xid status functions
+BEGIN;
+SELECT pg_current_xact_id() AS committed \gset
+COMMIT;
+BEGIN;
+SELECT pg_current_xact_id() AS rolledback \gset
+ROLLBACK;
+BEGIN;
+SELECT pg_current_xact_id() AS inprogress \gset
+SELECT pg_xact_status(:committed::text::xid8) AS committed;
+ committed
+-----------
+ committed
+(1 row)
+
+SELECT pg_xact_status(:rolledback::text::xid8) AS rolledback;
+ rolledback
+------------
+ aborted
+(1 row)
+
+SELECT pg_xact_status(:inprogress::text::xid8) AS inprogress;
+ inprogress
+-------------
+ in progress
+(1 row)
+
+SELECT pg_xact_status('1'::xid8); -- BootstrapTransactionId is always committed
+ pg_xact_status
+----------------
+ committed
+(1 row)
+
+SELECT pg_xact_status('2'::xid8); -- FrozenTransactionId is always committed
+ pg_xact_status
+----------------
+ committed
+(1 row)
+
+SELECT pg_xact_status('3'::xid8); -- in regress testing FirstNormalTransactionId will always be behind oldestXmin
+ pg_xact_status
+----------------
+
+(1 row)
+
+COMMIT;
+BEGIN;
+CREATE FUNCTION test_future_xid_status(xid8)
+RETURNS void
+LANGUAGE plpgsql
+AS
+$$
+BEGIN
+ PERFORM pg_xact_status($1);
+ RAISE EXCEPTION 'didn''t ERROR at xid in the future as expected';
+EXCEPTION
+ WHEN invalid_parameter_value THEN
+ RAISE NOTICE 'Got expected error for xid in the future';
+END;
+$$;
+SELECT test_future_xid_status((:inprogress + 10000)::text::xid8);
+NOTICE: Got expected error for xid in the future
+ test_future_xid_status
+------------------------
+
+(1 row)
+
+ROLLBACK;
diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql
index 8eca21823d6..fb5c9139d15 100644
--- a/src/test/regress/sql/alter_table.sql
+++ b/src/test/regress/sql/alter_table.sql
@@ -1645,7 +1645,7 @@ from pg_locks l join pg_class c on l.relation = c.oid
where virtualtransaction = (
select virtualtransaction
from pg_locks
- where transactionid = txid_current()::integer)
+ where transactionid = pg_current_xact_id()::xid)
and locktype = 'relation'
and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog')
and c.relname != 'my_locks'
@@ -1732,7 +1732,7 @@ from pg_locks l join pg_class c on l.relation = c.oid
where virtualtransaction = (
select virtualtransaction
from pg_locks
- where transactionid = txid_current()::integer)
+ where transactionid = pg_current_xact_id()::xid)
and locktype = 'relation'
and relnamespace != (select oid from pg_namespace where nspname = 'pg_catalog')
and c.relname = 'my_locks'
diff --git a/src/test/regress/sql/hs_standby_functions.sql b/src/test/regress/sql/hs_standby_functions.sql
index 251bac0a431..b57f67ff8b5 100644
--- a/src/test/regress/sql/hs_standby_functions.sql
+++ b/src/test/regress/sql/hs_standby_functions.sql
@@ -5,9 +5,9 @@
--
-- should fail
-select txid_current();
+select pg_current_xact_id();
-select length(txid_current_snapshot()::text) >= 4;
+select length(pg_current_snapshot()::text) >= 4;
select pg_start_backup('should fail');
select pg_switch_wal();
diff --git a/src/test/regress/sql/txid.sql b/src/test/regress/sql/txid.sql
index bd6decf0ef4..8d5ac98a892 100644
--- a/src/test/regress/sql/txid.sql
+++ b/src/test/regress/sql/txid.sql
@@ -1,4 +1,7 @@
-- txid_snapshot data type and related functions
+-- Note: these are backward-compatibility functions and types, and have been
+-- replaced by new xid8-based variants. See xid.sql. The txid variants will
+-- be removed in a future release.
-- i/o
select '12:13:'::txid_snapshot;
diff --git a/src/test/regress/sql/update.sql b/src/test/regress/sql/update.sql
index bb9c24e40f8..8c558a7bc72 100644
--- a/src/test/regress/sql/update.sql
+++ b/src/test/regress/sql/update.sql
@@ -117,18 +117,16 @@ INSERT INTO upsert_test VALUES (1, 'Bat') ON CONFLICT(a)
-- ON CONFLICT using system attributes in RETURNING, testing both the
-- inserting and updating paths. See bug report at:
-- https://www.postgresql.org/message-id/73436355-6432-49B1-92ED-1FE4F7E7E100%40finefun.com.au
-CREATE FUNCTION xid_current() RETURNS xid LANGUAGE SQL AS $$SELECT (txid_current() % ((1::int8<<32)))::text::xid;$$;
INSERT INTO upsert_test VALUES (2, 'Beeble') ON CONFLICT(a)
DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a)
- RETURNING tableoid::regclass, xmin = xid_current() AS xmin_correct, xmax = 0 AS xmax_correct;
+ RETURNING tableoid::regclass, xmin = pg_current_xact_id()::xid AS xmin_correct, xmax = 0 AS xmax_correct;
-- currently xmax is set after a conflict - that's probably not good,
-- but it seems worthwhile to have to be explicit if that changes.
INSERT INTO upsert_test VALUES (2, 'Brox') ON CONFLICT(a)
DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a)
- RETURNING tableoid::regclass, xmin = xid_current() AS xmin_correct, xmax = xid_current() AS xmax_correct;
+ RETURNING tableoid::regclass, xmin = pg_current_xact_id()::xid AS xmin_correct, xmax = pg_current_xact_id()::xid AS xmax_correct;
-DROP FUNCTION xid_current();
DROP TABLE update_test;
DROP TABLE upsert_test;
diff --git a/src/test/regress/sql/xid.sql b/src/test/regress/sql/xid.sql
index a4fbca51766..565714d4620 100644
--- a/src/test/regress/sql/xid.sql
+++ b/src/test/regress/sql/xid.sql
@@ -46,3 +46,107 @@ create table xid8_t1 (x xid8);
create index on xid8_t1 using btree(x);
create index on xid8_t1 using hash(x);
drop table xid8_t1;
+
+
+-- pg_snapshot data type and related functions
+
+-- Note: another set of tests similar to this exists in txid.sql, for a limited
+-- time (the relevant functions share C code)
+
+-- i/o
+select '12:13:'::pg_snapshot;
+select '12:18:14,16'::pg_snapshot;
+select '12:16:14,14'::pg_snapshot;
+
+-- errors
+select '31:12:'::pg_snapshot;
+select '0:1:'::pg_snapshot;
+select '12:13:0'::pg_snapshot;
+select '12:16:14,13'::pg_snapshot;
+
+create temp table snapshot_test (
+ nr integer,
+ snap pg_snapshot
+);
+
+insert into snapshot_test values (1, '12:13:');
+insert into snapshot_test values (2, '12:20:13,15,18');
+insert into snapshot_test values (3, '100001:100009:100005,100007,100008');
+insert into snapshot_test values (4, '100:150:101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131');
+select snap from snapshot_test order by nr;
+
+select pg_snapshot_xmin(snap),
+ pg_snapshot_xmax(snap),
+ pg_snapshot_xip(snap)
+from snapshot_test order by nr;
+
+select id, pg_visible_in_snapshot(id::text::xid8, snap)
+from snapshot_test, generate_series(11, 21) id
+where nr = 2;
+
+-- test bsearch
+select id, pg_visible_in_snapshot(id::text::xid8, snap)
+from snapshot_test, generate_series(90, 160) id
+where nr = 4;
+
+-- test current values also
+select pg_current_xact_id() >= pg_snapshot_xmin(pg_current_snapshot());
+
+-- we can't assume current is always less than xmax, however
+
+select pg_visible_in_snapshot(pg_current_xact_id(), pg_current_snapshot());
+
+-- test 64bitness
+
+select pg_snapshot '1000100010001000:1000100010001100:1000100010001012,1000100010001013';
+select pg_visible_in_snapshot('1000100010001012', '1000100010001000:1000100010001100:1000100010001012,1000100010001013');
+select pg_visible_in_snapshot('1000100010001015', '1000100010001000:1000100010001100:1000100010001012,1000100010001013');
+
+-- test 64bit overflow
+SELECT pg_snapshot '1:9223372036854775807:3';
+SELECT pg_snapshot '1:9223372036854775808:3';
+
+-- test pg_current_xact_id_if_assigned
+BEGIN;
+SELECT pg_current_xact_id_if_assigned() IS NULL;
+SELECT pg_current_xact_id() \gset
+SELECT pg_current_xact_id_if_assigned() IS NOT DISTINCT FROM xid8 :'pg_current_xact_id';
+COMMIT;
+
+-- test xid status functions
+BEGIN;
+SELECT pg_current_xact_id() AS committed \gset
+COMMIT;
+
+BEGIN;
+SELECT pg_current_xact_id() AS rolledback \gset
+ROLLBACK;
+
+BEGIN;
+SELECT pg_current_xact_id() AS inprogress \gset
+
+SELECT pg_xact_status(:committed::text::xid8) AS committed;
+SELECT pg_xact_status(:rolledback::text::xid8) AS rolledback;
+SELECT pg_xact_status(:inprogress::text::xid8) AS inprogress;
+SELECT pg_xact_status('1'::xid8); -- BootstrapTransactionId is always committed
+SELECT pg_xact_status('2'::xid8); -- FrozenTransactionId is always committed
+SELECT pg_xact_status('3'::xid8); -- in regress testing FirstNormalTransactionId will always be behind oldestXmin
+
+COMMIT;
+
+BEGIN;
+CREATE FUNCTION test_future_xid_status(xid8)
+RETURNS void
+LANGUAGE plpgsql
+AS
+$$
+BEGIN
+ PERFORM pg_xact_status($1);
+ RAISE EXCEPTION 'didn''t ERROR at xid in the future as expected';
+EXCEPTION
+ WHEN invalid_parameter_value THEN
+ RAISE NOTICE 'Got expected error for xid in the future';
+END;
+$$;
+SELECT test_future_xid_status((:inprogress + 10000)::text::xid8);
+ROLLBACK;
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 34623523a70..525d58e7f01 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -3099,6 +3099,7 @@ pg_sha224_ctx
pg_sha256_ctx
pg_sha384_ctx
pg_sha512_ctx
+pg_snapshot
pg_stack_base_t
pg_time_t
pg_tz