diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/utils/adt/Makefile | 2 | ||||
-rw-r--r-- | src/backend/utils/adt/xid8funcs.c (renamed from src/backend/utils/adt/txid.c) | 424 |
2 files changed, 180 insertions, 246 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)); |