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-2023, 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 "libpq/pqformat.h"
23 #include "utils/builtins.h"
24 #include "utils/xid8.h"
25 
26 #define PG_GETARG_COMMANDID(n) DatumGetCommandId(PG_GETARG_DATUM(n))
27 #define PG_RETURN_COMMANDID(x) return CommandIdGetDatum(x)
28 
29 
30 Datum
32 {
33  char *str = PG_GETARG_CSTRING(0);
34  TransactionId result;
35 
36  result = uint32in_subr(str, NULL, "xid", fcinfo->context);
38 }
39 
40 Datum
42 {
43  TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
44  char *result = (char *) palloc(16);
45 
46  snprintf(result, 16, "%lu", (unsigned long) transactionId);
47  PG_RETURN_CSTRING(result);
48 }
49 
50 /*
51  * xidrecv - converts external binary format to xid
52  */
53 Datum
55 {
57 
59 }
60 
61 /*
62  * xidsend - converts xid to binary format
63  */
64 Datum
66 {
69 
71  pq_sendint32(&buf, arg1);
73 }
74 
75 /*
76  * xideq - are two xids equal?
77  */
78 Datum
80 {
83 
85 }
86 
87 /*
88  * xidneq - are two xids different?
89  */
90 Datum
92 {
95 
96  PG_RETURN_BOOL(!TransactionIdEquals(xid1, xid2));
97 }
98 
99 /*
100  * xid_age - compute age of an XID (relative to latest stable xid)
101  */
102 Datum
104 {
107 
108  /* Permanent XIDs are always infinitely old */
109  if (!TransactionIdIsNormal(xid))
110  PG_RETURN_INT32(INT_MAX);
111 
112  PG_RETURN_INT32((int32) (now - xid));
113 }
114 
115 /*
116  * mxid_age - compute age of a multi XID (relative to latest stable mxid)
117  */
118 Datum
120 {
123 
124  if (!MultiXactIdIsValid(xid))
125  PG_RETURN_INT32(INT_MAX);
126 
127  PG_RETURN_INT32((int32) (now - xid));
128 }
129 
130 /*
131  * xidComparator
132  * qsort comparison function for XIDs
133  *
134  * We can't use wraparound comparison for XIDs because that does not respect
135  * the triangle inequality! Any old sort order will do.
136  */
137 int
138 xidComparator(const void *arg1, const void *arg2)
139 {
140  TransactionId xid1 = *(const TransactionId *) arg1;
141  TransactionId xid2 = *(const TransactionId *) arg2;
142 
143  if (xid1 > xid2)
144  return 1;
145  if (xid1 < xid2)
146  return -1;
147  return 0;
148 }
149 
150 /*
151  * xidLogicalComparator
152  * qsort comparison function for XIDs
153  *
154  * This is used to compare only XIDs from the same epoch (e.g. for backends
155  * running at the same time). So there must be only normal XIDs, so there's
156  * no issue with triangle inequality.
157  */
158 int
159 xidLogicalComparator(const void *arg1, const void *arg2)
160 {
161  TransactionId xid1 = *(const TransactionId *) arg1;
162  TransactionId xid2 = *(const TransactionId *) arg2;
163 
166 
167  if (TransactionIdPrecedes(xid1, xid2))
168  return -1;
169 
170  if (TransactionIdPrecedes(xid2, xid1))
171  return 1;
172 
173  return 0;
174 }
175 
176 Datum
178 {
180 
182 }
183 
184 Datum
186 {
187  char *str = PG_GETARG_CSTRING(0);
188  uint64 result;
189 
190  result = uint64in_subr(str, NULL, "xid8", fcinfo->context);
192 }
193 
194 Datum
196 {
198  char *result = (char *) palloc(21);
199 
200  snprintf(result, 21, UINT64_FORMAT, U64FromFullTransactionId(fxid));
201  PG_RETURN_CSTRING(result);
202 }
203 
204 Datum
206 {
208  uint64 value;
209 
210  value = (uint64) pq_getmsgint64(buf);
212 }
213 
214 Datum
216 {
219 
221  pq_sendint64(&buf, (uint64) U64FromFullTransactionId(arg1));
223 }
224 
225 Datum
227 {
230 
232 }
233 
234 Datum
236 {
239 
240  PG_RETURN_BOOL(!FullTransactionIdEquals(fxid1, fxid2));
241 }
242 
243 Datum
245 {
248 
250 }
251 
252 Datum
254 {
257 
259 }
260 
261 Datum
263 {
266 
268 }
269 
270 Datum
272 {
275 
277 }
278 
279 Datum
281 {
284 
285  if (FullTransactionIdFollows(fxid1, fxid2))
286  PG_RETURN_INT32(1);
287  else if (FullTransactionIdEquals(fxid1, fxid2))
288  PG_RETURN_INT32(0);
289  else
290  PG_RETURN_INT32(-1);
291 }
292 
293 Datum
295 {
298 
299  if (FullTransactionIdFollows(fxid1, fxid2))
301  else
303 }
304 
305 Datum
307 {
310 
311  if (FullTransactionIdPrecedes(fxid1, fxid2))
313  else
315 }
316 
317 /*****************************************************************************
318  * COMMAND IDENTIFIER ROUTINES *
319  *****************************************************************************/
320 
321 /*
322  * cidin - converts CommandId to internal representation.
323  */
324 Datum
326 {
327  char *str = PG_GETARG_CSTRING(0);
328  CommandId result;
329 
330  result = uint32in_subr(str, NULL, "cid", fcinfo->context);
331  PG_RETURN_COMMANDID(result);
332 }
333 
334 /*
335  * cidout - converts a cid to external representation.
336  */
337 Datum
339 {
341  char *result = (char *) palloc(16);
342 
343  snprintf(result, 16, "%lu", (unsigned long) c);
344  PG_RETURN_CSTRING(result);
345 }
346 
347 /*
348  * cidrecv - converts external binary format to cid
349  */
350 Datum
352 {
354 
356 }
357 
358 /*
359  * cidsend - converts cid to binary format
360  */
361 Datum
363 {
364  CommandId arg1 = PG_GETARG_COMMANDID(0);
366 
368  pq_sendint32(&buf, arg1);
370 }
371 
372 Datum
374 {
375  CommandId arg1 = PG_GETARG_COMMANDID(0);
376  CommandId arg2 = PG_GETARG_COMMANDID(1);
377 
378  PG_RETURN_BOOL(arg1 == arg2);
379 }
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1547
signed int int32
Definition: c.h:478
TransactionId MultiXactId
Definition: c.h:646
#define UINT64_FORMAT
Definition: c.h:533
uint32 CommandId
Definition: c.h:650
uint32 TransactionId
Definition: c.h:636
#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 @147 value
Assert(fmt[strlen(fmt) - 1] !='\n')
void * palloc(Size size)
Definition: mcxt.c:1226
MultiXactId ReadNextMultiXactId(void)
Definition: multixact.c:724
#define MultiXactIdIsValid(multi)
Definition: multixact.h:28
uint64 uint64in_subr(const char *s, char **endloc, const char *typname, Node *escontext)
Definition: numutils.c:736
uint32 uint32in_subr(const char *s, char **endloc, const char *typname, Node *escontext)
Definition: numutils.c:649
static char * buf
Definition: pg_test_fsync.c:67
#define snprintf
Definition: port.h:238
uintptr_t Datum
Definition: postgres.h:64
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:418
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:329
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:456
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:349
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145
static void pq_sendint64(StringInfo buf, uint64 i)
Definition: pqformat.h:153
char * c
StringInfoData * StringInfo
Definition: stringinfo.h:44
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:598
#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:27
Datum xidneq(PG_FUNCTION_ARGS)
Definition: xid.c:91
#define PG_GETARG_COMMANDID(n)
Definition: xid.c:26
int xidComparator(const void *arg1, const void *arg2)
Definition: xid.c:138
Datum xid8ge(PG_FUNCTION_ARGS)
Definition: xid.c:271
Datum cidin(PG_FUNCTION_ARGS)
Definition: xid.c:325
Datum xideq(PG_FUNCTION_ARGS)
Definition: xid.c:79
Datum cidout(PG_FUNCTION_ARGS)
Definition: xid.c:338
Datum xid_age(PG_FUNCTION_ARGS)
Definition: xid.c:103
Datum xid8toxid(PG_FUNCTION_ARGS)
Definition: xid.c:177
Datum xidrecv(PG_FUNCTION_ARGS)
Definition: xid.c:54
Datum xid8_larger(PG_FUNCTION_ARGS)
Definition: xid.c:294
int xidLogicalComparator(const void *arg1, const void *arg2)
Definition: xid.c:159
Datum xid8eq(PG_FUNCTION_ARGS)
Definition: xid.c:226
Datum xid8in(PG_FUNCTION_ARGS)
Definition: xid.c:185
Datum xid8_smaller(PG_FUNCTION_ARGS)
Definition: xid.c:306
Datum xid8cmp(PG_FUNCTION_ARGS)
Definition: xid.c:280
Datum cideq(PG_FUNCTION_ARGS)
Definition: xid.c:373
Datum xid8send(PG_FUNCTION_ARGS)
Definition: xid.c:215
Datum xid8gt(PG_FUNCTION_ARGS)
Definition: xid.c:253
Datum xidin(PG_FUNCTION_ARGS)
Definition: xid.c:31
Datum cidrecv(PG_FUNCTION_ARGS)
Definition: xid.c:351
Datum xid8lt(PG_FUNCTION_ARGS)
Definition: xid.c:244
Datum xidsend(PG_FUNCTION_ARGS)
Definition: xid.c:65
Datum xid8ne(PG_FUNCTION_ARGS)
Definition: xid.c:235
Datum xid8le(PG_FUNCTION_ARGS)
Definition: xid.c:262
Datum xid8recv(PG_FUNCTION_ARGS)
Definition: xid.c:205
Datum mxid_age(PG_FUNCTION_ARGS)
Definition: xid.c:119
Datum cidsend(PG_FUNCTION_ARGS)
Definition: xid.c:362
Datum xid8out(PG_FUNCTION_ARGS)
Definition: xid.c:195
Datum xidout(PG_FUNCTION_ARGS)
Definition: xid.c:41