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-2020, 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_TRANSACTIONID(n) DatumGetTransactionId(PG_GETARG_DATUM(n))
27 #define PG_RETURN_TRANSACTIONID(x) return TransactionIdGetDatum(x)
28 
29 #define PG_GETARG_COMMANDID(n) DatumGetCommandId(PG_GETARG_DATUM(n))
30 #define PG_RETURN_COMMANDID(x) return CommandIdGetDatum(x)
31 
32 
33 Datum
35 {
36  char *str = PG_GETARG_CSTRING(0);
37 
38  PG_RETURN_TRANSACTIONID((TransactionId) strtoul(str, NULL, 0));
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 
71  pq_begintypsend(&buf);
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  if (xid1 > xid2)
145  return 1;
146  if (xid1 < xid2)
147  return -1;
148  return 0;
149 }
150 
151 Datum
153 {
155 
157 }
158 
159 Datum
161 {
162  char *str = PG_GETARG_CSTRING(0);
163 
165 }
166 
167 Datum
169 {
171  char *result = (char *) palloc(21);
172 
173  snprintf(result, 21, UINT64_FORMAT, U64FromFullTransactionId(fxid));
174  PG_RETURN_CSTRING(result);
175 }
176 
177 Datum
179 {
181  uint64 value;
182 
183  value = (uint64) pq_getmsgint64(buf);
185 }
186 
187 Datum
189 {
192 
193  pq_begintypsend(&buf);
194  pq_sendint64(&buf, (uint64) U64FromFullTransactionId(arg1));
196 }
197 
198 Datum
200 {
203 
205 }
206 
207 Datum
209 {
212 
213  PG_RETURN_BOOL(!FullTransactionIdEquals(fxid1, fxid2));
214 }
215 
216 Datum
218 {
221 
223 }
224 
225 Datum
227 {
230 
232 }
233 
234 Datum
236 {
239 
241 }
242 
243 Datum
245 {
248 
250 }
251 
252 Datum
254 {
257 
258  if (FullTransactionIdFollows(fxid1, fxid2))
259  PG_RETURN_INT32(1);
260  else if (FullTransactionIdEquals(fxid1, fxid2))
261  PG_RETURN_INT32(0);
262  else
263  PG_RETURN_INT32(-1);
264 }
265 
266 /*****************************************************************************
267  * COMMAND IDENTIFIER ROUTINES *
268  *****************************************************************************/
269 
270 /*
271  * cidin - converts CommandId to internal representation.
272  */
273 Datum
275 {
276  char *str = PG_GETARG_CSTRING(0);
277 
278  PG_RETURN_COMMANDID((CommandId) strtoul(str, NULL, 0));
279 }
280 
281 /*
282  * cidout - converts a cid to external representation.
283  */
284 Datum
286 {
288  char *result = (char *) palloc(16);
289 
290  snprintf(result, 16, "%lu", (unsigned long) c);
291  PG_RETURN_CSTRING(result);
292 }
293 
294 /*
295  * cidrecv - converts external binary format to cid
296  */
297 Datum
299 {
301 
303 }
304 
305 /*
306  * cidsend - converts cid to binary format
307  */
308 Datum
310 {
311  CommandId arg1 = PG_GETARG_COMMANDID(0);
313 
314  pq_begintypsend(&buf);
315  pq_sendint32(&buf, arg1);
317 }
318 
319 Datum
321 {
322  CommandId arg1 = PG_GETARG_COMMANDID(0);
323  CommandId arg2 = PG_GETARG_COMMANDID(1);
324 
325  PG_RETURN_BOOL(arg1 == arg2);
326 }
Datum xid_age(PG_FUNCTION_ARGS)
Definition: xid.c:104
Datum cidin(PG_FUNCTION_ARGS)
Definition: xid.c:274
uint32 CommandId
Definition: c.h:527
#define PG_GETARG_FULLTRANSACTIONID(X)
Definition: xid8.h:19
Datum xidsend(PG_FUNCTION_ARGS)
Definition: xid.c:66
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
uint32 TransactionId
Definition: c.h:513
#define PG_RETURN_FULLTRANSACTIONID(X)
Definition: xid8.h:20
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
StringInfoData * StringInfo
Definition: stringinfo.h:44
Datum xidout(PG_FUNCTION_ARGS)
Definition: xid.c:42
#define PG_GETARG_COMMANDID(n)
Definition: xid.c:29
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
Datum xid8send(PG_FUNCTION_ARGS)
Definition: xid.c:188
Datum mxid_age(PG_FUNCTION_ARGS)
Definition: xid.c:120
Datum xideq(PG_FUNCTION_ARGS)
Definition: xid.c:80
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:369
static void pq_sendint64(StringInfo buf, uint64 i)
Definition: pqformat.h:153
static FullTransactionId FullTransactionIdFromU64(uint64 value)
Definition: transam.h:79
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
#define PG_RETURN_COMMANDID(x)
Definition: xid.c:30
signed int int32
Definition: c.h:355
Datum cideq(PG_FUNCTION_ARGS)
Definition: xid.c:320
#define XidFromFullTransactionId(x)
Definition: transam.h:48
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145
#define FullTransactionIdPrecedesOrEquals(a, b)
Definition: transam.h:52
Datum cidrecv(PG_FUNCTION_ARGS)
Definition: xid.c:298
Datum xid8cmp(PG_FUNCTION_ARGS)
Definition: xid.c:253
#define FullTransactionIdFollows(a, b)
Definition: transam.h:53
Datum xidin(PG_FUNCTION_ARGS)
Definition: xid.c:34
char * c
static char * buf
Definition: pg_test_fsync.c:67
Datum cidsend(PG_FUNCTION_ARGS)
Definition: xid.c:309
Datum xid8recv(PG_FUNCTION_ARGS)
Definition: xid.c:178
#define MultiXactIdIsValid(multi)
Definition: multixact.h:27
Datum xidrecv(PG_FUNCTION_ARGS)
Definition: xid.c:55
Datum xid8in(PG_FUNCTION_ARGS)
Definition: xid.c:160
Datum xid8lt(PG_FUNCTION_ARGS)
Definition: xid.c:217
Datum xid8ge(PG_FUNCTION_ARGS)
Definition: xid.c:244
TransactionId GetStableLatestTransactionId(void)
Definition: xact.c:526
uint64 pg_strtouint64(const char *str, char **endptr, int base)
Definition: numutils.c:621
Datum xid8ne(PG_FUNCTION_ARGS)
Definition: xid.c:208
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
uintptr_t Datum
Definition: postgres.h:367
Datum cidout(PG_FUNCTION_ARGS)
Definition: xid.c:285
static struct @143 value
#define FullTransactionIdEquals(a, b)
Definition: transam.h:50
TransactionId MultiXactId
Definition: c.h:523
#define U64FromFullTransactionId(x)
Definition: transam.h:49
#define FullTransactionIdFollowsOrEquals(a, b)
Definition: transam.h:54
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:361
Datum xid8le(PG_FUNCTION_ARGS)
Definition: xid.c:235
Datum xidneq(PG_FUNCTION_ARGS)
Definition: xid.c:92
void * palloc(Size size)
Definition: mcxt.c:949
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:455
#define PG_GETARG_TRANSACTIONID(n)
Definition: xid.c:26
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:417
#define FullTransactionIdPrecedes(a, b)
Definition: transam.h:51
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
#define snprintf
Definition: port.h:193
#define UINT64_FORMAT
Definition: c.h:410
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1538
Datum xid8eq(PG_FUNCTION_ARGS)
Definition: xid.c:199
Datum xid8out(PG_FUNCTION_ARGS)
Definition: xid.c:168
int xidComparator(const void *arg1, const void *arg2)
Definition: xid.c:139
MultiXactId ReadNextMultiXactId(void)
Definition: multixact.c:723
Datum xid8toxid(PG_FUNCTION_ARGS)
Definition: xid.c:152
Datum xid8gt(PG_FUNCTION_ARGS)
Definition: xid.c:226
#define PG_RETURN_TRANSACTIONID(x)
Definition: xid.c:27