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-2024, 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/int.h"
23 #include "libpq/pqformat.h"
24 #include "utils/builtins.h"
25 #include "utils/xid8.h"
26 
27 #define PG_GETARG_COMMANDID(n) DatumGetCommandId(PG_GETARG_DATUM(n))
28 #define PG_RETURN_COMMANDID(x) return CommandIdGetDatum(x)
29 
30 
31 Datum
33 {
34  char *str = PG_GETARG_CSTRING(0);
35  TransactionId result;
36 
37  result = uint32in_subr(str, NULL, "xid", fcinfo->context);
39 }
40 
41 Datum
43 {
44  TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
45  char *result = (char *) palloc(16);
46 
47  snprintf(result, 16, "%lu", (unsigned long) transactionId);
48  PG_RETURN_CSTRING(result);
49 }
50 
51 /*
52  * xidrecv - converts external binary format to xid
53  */
54 Datum
56 {
58 
60 }
61 
62 /*
63  * xidsend - converts xid to binary format
64  */
65 Datum
67 {
70 
72  pq_sendint32(&buf, arg1);
74 }
75 
76 /*
77  * xideq - are two xids equal?
78  */
79 Datum
81 {
84 
86 }
87 
88 /*
89  * xidneq - are two xids different?
90  */
91 Datum
93 {
96 
97  PG_RETURN_BOOL(!TransactionIdEquals(xid1, xid2));
98 }
99 
100 /*
101  * xid_age - compute age of an XID (relative to latest stable xid)
102  */
103 Datum
105 {
108 
109  /* Permanent XIDs are always infinitely old */
110  if (!TransactionIdIsNormal(xid))
111  PG_RETURN_INT32(INT_MAX);
112 
113  PG_RETURN_INT32((int32) (now - xid));
114 }
115 
116 /*
117  * mxid_age - compute age of a multi XID (relative to latest stable mxid)
118  */
119 Datum
121 {
124 
125  if (!MultiXactIdIsValid(xid))
126  PG_RETURN_INT32(INT_MAX);
127 
128  PG_RETURN_INT32((int32) (now - xid));
129 }
130 
131 /*
132  * xidComparator
133  * qsort comparison function for XIDs
134  *
135  * We can't use wraparound comparison for XIDs because that does not respect
136  * the triangle inequality! Any old sort order will do.
137  */
138 int
139 xidComparator(const void *arg1, const void *arg2)
140 {
141  TransactionId xid1 = *(const TransactionId *) arg1;
142  TransactionId xid2 = *(const TransactionId *) arg2;
143 
144  return pg_cmp_u32(xid1, xid2);
145 }
146 
147 /*
148  * xidLogicalComparator
149  * qsort comparison function for XIDs
150  *
151  * This is used to compare only XIDs from the same epoch (e.g. for backends
152  * running at the same time). So there must be only normal XIDs, so there's
153  * no issue with triangle inequality.
154  */
155 int
156 xidLogicalComparator(const void *arg1, const void *arg2)
157 {
158  TransactionId xid1 = *(const TransactionId *) arg1;
159  TransactionId xid2 = *(const TransactionId *) arg2;
160 
163 
164  if (TransactionIdPrecedes(xid1, xid2))
165  return -1;
166 
167  if (TransactionIdPrecedes(xid2, xid1))
168  return 1;
169 
170  return 0;
171 }
172 
173 Datum
175 {
177 
179 }
180 
181 Datum
183 {
184  char *str = PG_GETARG_CSTRING(0);
185  uint64 result;
186 
187  result = uint64in_subr(str, NULL, "xid8", fcinfo->context);
189 }
190 
191 Datum
193 {
195  char *result = (char *) palloc(21);
196 
197  snprintf(result, 21, UINT64_FORMAT, U64FromFullTransactionId(fxid));
198  PG_RETURN_CSTRING(result);
199 }
200 
201 Datum
203 {
205  uint64 value;
206 
207  value = (uint64) pq_getmsgint64(buf);
209 }
210 
211 Datum
213 {
216 
218  pq_sendint64(&buf, (uint64) U64FromFullTransactionId(arg1));
220 }
221 
222 Datum
224 {
227 
229 }
230 
231 Datum
233 {
236 
237  PG_RETURN_BOOL(!FullTransactionIdEquals(fxid1, fxid2));
238 }
239 
240 Datum
242 {
245 
247 }
248 
249 Datum
251 {
254 
256 }
257 
258 Datum
260 {
263 
265 }
266 
267 Datum
269 {
272 
274 }
275 
276 Datum
278 {
281 
282  if (FullTransactionIdFollows(fxid1, fxid2))
283  PG_RETURN_INT32(1);
284  else if (FullTransactionIdEquals(fxid1, fxid2))
285  PG_RETURN_INT32(0);
286  else
287  PG_RETURN_INT32(-1);
288 }
289 
290 Datum
292 {
295 
296  if (FullTransactionIdFollows(fxid1, fxid2))
298  else
300 }
301 
302 Datum
304 {
307 
308  if (FullTransactionIdPrecedes(fxid1, fxid2))
310  else
312 }
313 
314 /*****************************************************************************
315  * COMMAND IDENTIFIER ROUTINES *
316  *****************************************************************************/
317 
318 /*
319  * cidin - converts CommandId to internal representation.
320  */
321 Datum
323 {
324  char *str = PG_GETARG_CSTRING(0);
325  CommandId result;
326 
327  result = uint32in_subr(str, NULL, "cid", fcinfo->context);
328  PG_RETURN_COMMANDID(result);
329 }
330 
331 /*
332  * cidout - converts a cid to external representation.
333  */
334 Datum
336 {
338  char *result = (char *) palloc(16);
339 
340  snprintf(result, 16, "%lu", (unsigned long) c);
341  PG_RETURN_CSTRING(result);
342 }
343 
344 /*
345  * cidrecv - converts external binary format to cid
346  */
347 Datum
349 {
351 
353 }
354 
355 /*
356  * cidsend - converts cid to binary format
357  */
358 Datum
360 {
361  CommandId arg1 = PG_GETARG_COMMANDID(0);
363 
365  pq_sendint32(&buf, arg1);
367 }
368 
369 Datum
371 {
372  CommandId arg1 = PG_GETARG_COMMANDID(0);
373  CommandId arg2 = PG_GETARG_COMMANDID(1);
374 
375  PG_RETURN_BOOL(arg1 == arg2);
376 }
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1618
signed int int32
Definition: c.h:481
TransactionId MultiXactId
Definition: c.h:649
#define UINT64_FORMAT
Definition: c.h:536
uint32 CommandId
Definition: c.h:653
uint32 TransactionId
Definition: c.h:639
#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_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 struct @150 value
static int pg_cmp_u32(uint32 a, uint32 b)
Definition: int.h:489
Assert(fmt[strlen(fmt) - 1] !='\n')
void * palloc(Size size)
Definition: mcxt.c:1304
MultiXactId ReadNextMultiXactId(void)
Definition: multixact.c:722
#define MultiXactIdIsValid(multi)
Definition: multixact.h:28
uint64 uint64in_subr(const char *s, char **endloc, const char *typname, Node *escontext)
Definition: numutils.c:987
uint32 uint32in_subr(const char *s, char **endloc, const char *typname, Node *escontext)
Definition: numutils.c:900
static char * buf
Definition: pg_test_fsync.c:73
#define snprintf
Definition: port.h:238
uintptr_t Datum
Definition: postgres.h:64
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:599
#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:28
Datum xidneq(PG_FUNCTION_ARGS)
Definition: xid.c:92
#define PG_GETARG_COMMANDID(n)
Definition: xid.c:27
int xidComparator(const void *arg1, const void *arg2)
Definition: xid.c:139
Datum xid8ge(PG_FUNCTION_ARGS)
Definition: xid.c:268
Datum cidin(PG_FUNCTION_ARGS)
Definition: xid.c:322
Datum xideq(PG_FUNCTION_ARGS)
Definition: xid.c:80
Datum cidout(PG_FUNCTION_ARGS)
Definition: xid.c:335
Datum xid_age(PG_FUNCTION_ARGS)
Definition: xid.c:104
Datum xid8toxid(PG_FUNCTION_ARGS)
Definition: xid.c:174
Datum xidrecv(PG_FUNCTION_ARGS)
Definition: xid.c:55
Datum xid8_larger(PG_FUNCTION_ARGS)
Definition: xid.c:291
int xidLogicalComparator(const void *arg1, const void *arg2)
Definition: xid.c:156
Datum xid8eq(PG_FUNCTION_ARGS)
Definition: xid.c:223
Datum xid8in(PG_FUNCTION_ARGS)
Definition: xid.c:182
Datum xid8_smaller(PG_FUNCTION_ARGS)
Definition: xid.c:303
Datum xid8cmp(PG_FUNCTION_ARGS)
Definition: xid.c:277
Datum cideq(PG_FUNCTION_ARGS)
Definition: xid.c:370
Datum xid8send(PG_FUNCTION_ARGS)
Definition: xid.c:212
Datum xid8gt(PG_FUNCTION_ARGS)
Definition: xid.c:250
Datum xidin(PG_FUNCTION_ARGS)
Definition: xid.c:32
Datum cidrecv(PG_FUNCTION_ARGS)
Definition: xid.c:348
Datum xid8lt(PG_FUNCTION_ARGS)
Definition: xid.c:241
Datum xidsend(PG_FUNCTION_ARGS)
Definition: xid.c:66
Datum xid8ne(PG_FUNCTION_ARGS)
Definition: xid.c:232
Datum xid8le(PG_FUNCTION_ARGS)
Definition: xid.c:259
Datum xid8recv(PG_FUNCTION_ARGS)
Definition: xid.c:202
Datum mxid_age(PG_FUNCTION_ARGS)
Definition: xid.c:120
Datum cidsend(PG_FUNCTION_ARGS)
Definition: xid.c:359
Datum xid8out(PG_FUNCTION_ARGS)
Definition: xid.c:192
Datum xidout(PG_FUNCTION_ARGS)
Definition: xid.c:42