PostgreSQL Source Code git master
xid.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * xid.c
4 * POSTGRES transaction identifier and command identifier datatypes.
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/utils/adt/xid.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "postgres.h"
16
17#include <limits.h>
18
19#include "access/multixact.h"
20#include "access/transam.h"
21#include "access/xact.h"
22#include "common/hashfn.h"
23#include "common/int.h"
24#include "libpq/pqformat.h"
25#include "utils/builtins.h"
26#include "utils/xid8.h"
27
28#define PG_GETARG_COMMANDID(n) DatumGetCommandId(PG_GETARG_DATUM(n))
29#define PG_RETURN_COMMANDID(x) return CommandIdGetDatum(x)
30
31
34{
35 char *str = PG_GETARG_CSTRING(0);
36 TransactionId result;
37
38 result = uint32in_subr(str, NULL, "xid", fcinfo->context);
40}
41
44{
45 TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
46 char *result = (char *) palloc(16);
47
48 snprintf(result, 16, "%lu", (unsigned long) transactionId);
49 PG_RETURN_CSTRING(result);
50}
51
52/*
53 * xidrecv - converts external binary format to xid
54 */
57{
59
61}
62
63/*
64 * xidsend - converts xid to binary format
65 */
68{
71
73 pq_sendint32(&buf, arg1);
75}
76
77/*
78 * xideq - are two xids equal?
79 */
82{
85
87}
88
89/*
90 * xidneq - are two xids different?
91 */
94{
97
99}
100
101Datum
103{
105}
106
107Datum
109{
111}
112
113/*
114 * xid_age - compute age of an XID (relative to latest stable xid)
115 */
116Datum
118{
121
122 /* Permanent XIDs are always infinitely old */
123 if (!TransactionIdIsNormal(xid))
124 PG_RETURN_INT32(INT_MAX);
125
126 PG_RETURN_INT32((int32) (now - xid));
127}
128
129/*
130 * mxid_age - compute age of a multi XID (relative to latest stable mxid)
131 */
132Datum
134{
137
138 if (!MultiXactIdIsValid(xid))
139 PG_RETURN_INT32(INT_MAX);
140
141 PG_RETURN_INT32((int32) (now - xid));
142}
143
144/*
145 * xidComparator
146 * qsort comparison function for XIDs
147 *
148 * We can't use wraparound comparison for XIDs because that does not respect
149 * the triangle inequality! Any old sort order will do.
150 */
151int
152xidComparator(const void *arg1, const void *arg2)
153{
154 TransactionId xid1 = *(const TransactionId *) arg1;
155 TransactionId xid2 = *(const TransactionId *) arg2;
156
157 return pg_cmp_u32(xid1, xid2);
158}
159
160/*
161 * xidLogicalComparator
162 * qsort comparison function for XIDs
163 *
164 * This is used to compare only XIDs from the same epoch (e.g. for backends
165 * running at the same time). So there must be only normal XIDs, so there's
166 * no issue with triangle inequality.
167 */
168int
169xidLogicalComparator(const void *arg1, const void *arg2)
170{
171 TransactionId xid1 = *(const TransactionId *) arg1;
172 TransactionId xid2 = *(const TransactionId *) arg2;
173
176
177 if (TransactionIdPrecedes(xid1, xid2))
178 return -1;
179
180 if (TransactionIdPrecedes(xid2, xid1))
181 return 1;
182
183 return 0;
184}
185
186Datum
188{
190
192}
193
194Datum
196{
197 char *str = PG_GETARG_CSTRING(0);
198 uint64 result;
199
200 result = uint64in_subr(str, NULL, "xid8", fcinfo->context);
202}
203
204Datum
206{
208 char *result = (char *) palloc(21);
209
211 PG_RETURN_CSTRING(result);
212}
213
214Datum
216{
219
222}
223
224Datum
226{
229
233}
234
235Datum
237{
240
242}
243
244Datum
246{
249
251}
252
253Datum
255{
258
260}
261
262Datum
264{
267
269}
270
271Datum
273{
276
278}
279
280Datum
282{
285
287}
288
289Datum
291{
294
295 if (FullTransactionIdFollows(fxid1, fxid2))
297 else if (FullTransactionIdEquals(fxid1, fxid2))
299 else
300 PG_RETURN_INT32(-1);
301}
302
303Datum
305{
306 return hashint8(fcinfo);
307}
308
309Datum
311{
312 return hashint8extended(fcinfo);
313}
314
315Datum
317{
320
321 if (FullTransactionIdFollows(fxid1, fxid2))
323 else
325}
326
327Datum
329{
332
333 if (FullTransactionIdPrecedes(fxid1, fxid2))
335 else
337}
338
339/*****************************************************************************
340 * COMMAND IDENTIFIER ROUTINES *
341 *****************************************************************************/
342
343/*
344 * cidin - converts CommandId to internal representation.
345 */
346Datum
348{
349 char *str = PG_GETARG_CSTRING(0);
350 CommandId result;
351
352 result = uint32in_subr(str, NULL, "cid", fcinfo->context);
353 PG_RETURN_COMMANDID(result);
354}
355
356/*
357 * cidout - converts a cid to external representation.
358 */
359Datum
361{
363 char *result = (char *) palloc(16);
364
365 snprintf(result, 16, "%lu", (unsigned long) c);
366 PG_RETURN_CSTRING(result);
367}
368
369/*
370 * cidrecv - converts external binary format to cid
371 */
372Datum
374{
376
378}
379
380/*
381 * cidsend - converts cid to binary format
382 */
383Datum
385{
388
390 pq_sendint32(&buf, arg1);
392}
393
394Datum
396{
399
400 PG_RETURN_BOOL(arg1 == arg2);
401}
402
403Datum
405{
407}
408
409Datum
411{
413}
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1608
TransactionId MultiXactId
Definition: c.h:633
#define UINT64_FORMAT
Definition: c.h:521
int32_t int32
Definition: c.h:498
uint64_t uint64
Definition: c.h:503
uint32 CommandId
Definition: c.h:637
uint32 TransactionId
Definition: c.h:623
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
#define PG_RETURN_TRANSACTIONID(x)
Definition: fmgr.h:364
#define PG_GETARG_TRANSACTIONID(n)
Definition: fmgr.h:279
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static Datum hash_uint32(uint32 k)
Definition: hashfn.h:43
static Datum hash_uint32_extended(uint32 k, uint64 seed)
Definition: hashfn.h:49
Assert(PointerIsAligned(start, uint64))
const char * str
Datum hashint8extended(PG_FUNCTION_ARGS)
Definition: hashfunc.c:103
Datum hashint8(PG_FUNCTION_ARGS)
Definition: hashfunc.c:83
static struct @165 value
static int pg_cmp_u32(uint32 a, uint32 b)
Definition: int.h:652
void * palloc(Size size)
Definition: mcxt.c:1317
MultiXactId ReadNextMultiXactId(void)
Definition: multixact.c:771
#define MultiXactIdIsValid(multi)
Definition: multixact.h:28
uint64 uint64in_subr(const char *s, char **endloc, const char *typname, Node *escontext)
Definition: numutils.c:985
uint32 uint32in_subr(const char *s, char **endloc, const char *typname, Node *escontext)
Definition: numutils.c:898
static char * buf
Definition: pg_test_fsync.c:72
#define snprintf
Definition: port.h:239
uintptr_t Datum
Definition: postgres.h:69
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:415
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:453
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:144
static void pq_sendint64(StringInfo buf, uint64 i)
Definition: pqformat.h:152
char * c
StringInfoData * StringInfo
Definition: stringinfo.h:54
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:280
#define FullTransactionIdEquals(a, b)
Definition: transam.h:50
#define FullTransactionIdPrecedesOrEquals(a, b)
Definition: transam.h:52
#define U64FromFullTransactionId(x)
Definition: transam.h:49
static FullTransactionId FullTransactionIdFromU64(uint64 value)
Definition: transam.h:81
#define FullTransactionIdFollowsOrEquals(a, b)
Definition: transam.h:54
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
#define FullTransactionIdFollows(a, b)
Definition: transam.h:53
#define XidFromFullTransactionId(x)
Definition: transam.h:48
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
#define FullTransactionIdPrecedes(a, b)
Definition: transam.h:51
TransactionId GetStableLatestTransactionId(void)
Definition: xact.c:607
#define PG_GETARG_FULLTRANSACTIONID(X)
Definition: xid8.h:29
#define PG_RETURN_FULLTRANSACTIONID(X)
Definition: xid8.h:30
#define PG_RETURN_COMMANDID(x)
Definition: xid.c:29
Datum xidneq(PG_FUNCTION_ARGS)
Definition: xid.c:93
Datum hashxid(PG_FUNCTION_ARGS)
Definition: xid.c:102
#define PG_GETARG_COMMANDID(n)
Definition: xid.c:28
int xidComparator(const void *arg1, const void *arg2)
Definition: xid.c:152
Datum xid8ge(PG_FUNCTION_ARGS)
Definition: xid.c:281
Datum cidin(PG_FUNCTION_ARGS)
Definition: xid.c:347
Datum xideq(PG_FUNCTION_ARGS)
Definition: xid.c:81
Datum hashcid(PG_FUNCTION_ARGS)
Definition: xid.c:404
Datum cidout(PG_FUNCTION_ARGS)
Definition: xid.c:360
Datum xid_age(PG_FUNCTION_ARGS)
Definition: xid.c:117
Datum xid8toxid(PG_FUNCTION_ARGS)
Definition: xid.c:187
Datum hashxid8(PG_FUNCTION_ARGS)
Definition: xid.c:304
Datum xidrecv(PG_FUNCTION_ARGS)
Definition: xid.c:56
Datum xid8_larger(PG_FUNCTION_ARGS)
Definition: xid.c:316
int xidLogicalComparator(const void *arg1, const void *arg2)
Definition: xid.c:169
Datum xid8eq(PG_FUNCTION_ARGS)
Definition: xid.c:236
Datum hashcidextended(PG_FUNCTION_ARGS)
Definition: xid.c:410
Datum xid8in(PG_FUNCTION_ARGS)
Definition: xid.c:195
Datum xid8_smaller(PG_FUNCTION_ARGS)
Definition: xid.c:328
Datum xid8cmp(PG_FUNCTION_ARGS)
Definition: xid.c:290
Datum cideq(PG_FUNCTION_ARGS)
Definition: xid.c:395
Datum xid8send(PG_FUNCTION_ARGS)
Definition: xid.c:225
Datum xid8gt(PG_FUNCTION_ARGS)
Definition: xid.c:263
Datum xidin(PG_FUNCTION_ARGS)
Definition: xid.c:33
Datum cidrecv(PG_FUNCTION_ARGS)
Definition: xid.c:373
Datum xid8lt(PG_FUNCTION_ARGS)
Definition: xid.c:254
Datum xidsend(PG_FUNCTION_ARGS)
Definition: xid.c:67
Datum xid8ne(PG_FUNCTION_ARGS)
Definition: xid.c:245
Datum xid8le(PG_FUNCTION_ARGS)
Definition: xid.c:272
Datum hashxidextended(PG_FUNCTION_ARGS)
Definition: xid.c:108
Datum xid8recv(PG_FUNCTION_ARGS)
Definition: xid.c:215
Datum mxid_age(PG_FUNCTION_ARGS)
Definition: xid.c:133
Datum cidsend(PG_FUNCTION_ARGS)
Definition: xid.c:384
Datum xid8out(PG_FUNCTION_ARGS)
Definition: xid.c:205
Datum hashxid8extended(PG_FUNCTION_ARGS)
Definition: xid.c:310
Datum xidout(PG_FUNCTION_ARGS)
Definition: xid.c:43