1 /*-------------------------------------------------------------------------
4 * POSTGRES transaction identifier and command identifier datatypes.
6 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/utils/adt/xid.c
13 *-------------------------------------------------------------------------
19 #include "access/transam.h"
20 #include "access/xact.h"
21 #include "libpq/pqformat.h"
22 #include "utils/builtins.h"
24 #define PG_GETARG_TRANSACTIONID(n) DatumGetTransactionId(PG_GETARG_DATUM(n))
25 #define PG_RETURN_TRANSACTIONID(x) return TransactionIdGetDatum(x)
27 #define PG_GETARG_COMMANDID(n) DatumGetCommandId(PG_GETARG_DATUM(n))
28 #define PG_RETURN_COMMANDID(x) return CommandIdGetDatum(x)
32 xidin(PG_FUNCTION_ARGS)
34 char *str = PG_GETARG_CSTRING(0);
36 PG_RETURN_TRANSACTIONID((TransactionId) strtoul(str, NULL, 0));
40 xidout(PG_FUNCTION_ARGS)
42 TransactionId transactionId = PG_GETARG_TRANSACTIONID(0);
44 /* maximum 32 bit unsigned integer representation takes 10 chars */
45 char *str = palloc(11);
47 snprintf(str, 11, "%lu", (unsigned long) transactionId);
49 PG_RETURN_CSTRING(str);
53 * xidrecv - converts external binary format to xid
56 xidrecv(PG_FUNCTION_ARGS)
58 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
60 PG_RETURN_TRANSACTIONID((TransactionId) pq_getmsgint(buf, sizeof(TransactionId)));
64 * xidsend - converts xid to binary format
67 xidsend(PG_FUNCTION_ARGS)
69 TransactionId arg1 = PG_GETARG_TRANSACTIONID(0);
72 pq_begintypsend(&buf);
73 pq_sendint(&buf, arg1, sizeof(arg1));
74 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
78 * xideq - are two xids equal?
81 xideq(PG_FUNCTION_ARGS)
83 TransactionId xid1 = PG_GETARG_TRANSACTIONID(0);
84 TransactionId xid2 = PG_GETARG_TRANSACTIONID(1);
86 PG_RETURN_BOOL(TransactionIdEquals(xid1, xid2));
90 * xid_age - compute age of an XID (relative to current xact)
93 xid_age(PG_FUNCTION_ARGS)
95 TransactionId xid = PG_GETARG_TRANSACTIONID(0);
96 TransactionId now = GetTopTransactionId();
98 /* Permanent XIDs are always infinitely old */
99 if (!TransactionIdIsNormal(xid))
100 PG_RETURN_INT32(INT_MAX);
102 PG_RETURN_INT32((int32) (now - xid));
107 * qsort comparison function for XIDs
109 * We can't use wraparound comparison for XIDs because that does not respect
110 * the triangle inequality! Any old sort order will do.
113 xidComparator(const void *arg1, const void *arg2)
115 TransactionId xid1 = *(const TransactionId *) arg1;
116 TransactionId xid2 = *(const TransactionId *) arg2;
125 /*****************************************************************************
126 * COMMAND IDENTIFIER ROUTINES *
127 *****************************************************************************/
130 * cidin - converts CommandId to internal representation.
133 cidin(PG_FUNCTION_ARGS)
135 char *s = PG_GETARG_CSTRING(0);
140 PG_RETURN_COMMANDID(c);
144 * cidout - converts a cid to external representation.
147 cidout(PG_FUNCTION_ARGS)
149 CommandId c = PG_GETARG_COMMANDID(0);
150 char *result = (char *) palloc(16);
152 snprintf(result, 16, "%u", (unsigned int) c);
153 PG_RETURN_CSTRING(result);
157 * cidrecv - converts external binary format to cid
160 cidrecv(PG_FUNCTION_ARGS)
162 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
164 PG_RETURN_COMMANDID((CommandId) pq_getmsgint(buf, sizeof(CommandId)));
168 * cidsend - converts cid to binary format
171 cidsend(PG_FUNCTION_ARGS)
173 CommandId arg1 = PG_GETARG_COMMANDID(0);
176 pq_begintypsend(&buf);
177 pq_sendint(&buf, arg1, sizeof(arg1));
178 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
182 cideq(PG_FUNCTION_ARGS)
184 CommandId arg1 = PG_GETARG_COMMANDID(0);
185 CommandId arg2 = PG_GETARG_COMMANDID(1);
187 PG_RETURN_BOOL(arg1 == arg2);