Skip to content

Commit aeec457

Browse files
committed
Add SQL type xid8 to expose FullTransactionId to users.
Similar to xid, but 64 bits wide. This new type is suitable for use in various system views and administration functions. Reviewed-by: Fujii Masao <masao.fujii@oss.nttdata.com> Reviewed-by: Takao Fujii <btfujiitkp@oss.nttdata.com> Reviewed-by: Yoshikazu Imai <imai.yoshikazu@fujitsu.com> Reviewed-by: Mark Dilger <mark.dilger@enterprisedb.com> Discussion: https://postgr.es/m/20190725000636.666m5mad25wfbrri%40alap3.anarazel.de
1 parent 4bea576 commit aeec457

File tree

20 files changed

+464
-2
lines changed

20 files changed

+464
-2
lines changed

doc/src/sgml/datatype.sgml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4516,6 +4516,10 @@ INSERT INTO mytable VALUES(-1); -- fails
45164516
<primary>regtype</primary>
45174517
</indexterm>
45184518

4519+
<indexterm zone="datatype-oid">
4520+
<primary>xid8</primary>
4521+
</indexterm>
4522+
45194523
<indexterm zone="datatype-oid">
45204524
<primary>cid</primary>
45214525
</indexterm>
@@ -4719,6 +4723,9 @@ SELECT * FROM pg_attribute
47194723
Another identifier type used by the system is <type>xid</type>, or transaction
47204724
(abbreviated <abbrev>xact</abbrev>) identifier. This is the data type of the system columns
47214725
<structfield>xmin</structfield> and <structfield>xmax</structfield>. Transaction identifiers are 32-bit quantities.
4726+
In some contexts, a 64-bit variant <type>xid8</type> is used. Unlike
4727+
<type>xid</type> values, <type>xid8</type> values increase strictly
4728+
monotonically and cannot be reused in the lifetime of a database cluster.
47224729
</para>
47234730

47244731
<para>

src/backend/access/hash/hashvalidate.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,9 @@ check_hash_func_signature(Oid funcid, int16 amprocnum, Oid argtype)
317317
(argtype == DATEOID ||
318318
argtype == XIDOID || argtype == CIDOID))
319319
/* okay, allowed use of hashint4() */ ;
320+
else if ((funcid == F_HASHINT8 || funcid == F_HASHINT8EXTENDED) &&
321+
(argtype == XID8OID))
322+
/* okay, allowed use of hashint8() */ ;
320323
else if ((funcid == F_TIMESTAMP_HASH ||
321324
funcid == F_TIMESTAMP_HASH_EXTENDED) &&
322325
argtype == TIMESTAMPTZOID)

src/backend/utils/adt/xid.c

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "access/xact.h"
2222
#include "libpq/pqformat.h"
2323
#include "utils/builtins.h"
24+
#include "utils/xid8.h"
2425

2526
#define PG_GETARG_TRANSACTIONID(n) DatumGetTransactionId(PG_GETARG_DATUM(n))
2627
#define PG_RETURN_TRANSACTIONID(x) return TransactionIdGetDatum(x)
@@ -147,6 +148,121 @@ xidComparator(const void *arg1, const void *arg2)
147148
return 0;
148149
}
149150

151+
Datum
152+
xid8toxid(PG_FUNCTION_ARGS)
153+
{
154+
FullTransactionId fxid = PG_GETARG_FULLTRANSACTIONID(0);
155+
156+
PG_RETURN_TRANSACTIONID(XidFromFullTransactionId(fxid));
157+
}
158+
159+
Datum
160+
xid8in(PG_FUNCTION_ARGS)
161+
{
162+
char *str = PG_GETARG_CSTRING(0);
163+
164+
PG_RETURN_FULLTRANSACTIONID(FullTransactionIdFromU64(pg_strtouint64(str, NULL, 0)));
165+
}
166+
167+
Datum
168+
xid8out(PG_FUNCTION_ARGS)
169+
{
170+
FullTransactionId fxid = PG_GETARG_FULLTRANSACTIONID(0);
171+
char *result = (char *) palloc(21);
172+
173+
snprintf(result, 21, UINT64_FORMAT, U64FromFullTransactionId(fxid));
174+
PG_RETURN_CSTRING(result);
175+
}
176+
177+
Datum
178+
xid8recv(PG_FUNCTION_ARGS)
179+
{
180+
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
181+
uint64 value;
182+
183+
value = (uint64) pq_getmsgint64(buf);
184+
PG_RETURN_FULLTRANSACTIONID(FullTransactionIdFromU64(value));
185+
}
186+
187+
Datum
188+
xid8send(PG_FUNCTION_ARGS)
189+
{
190+
FullTransactionId arg1 = PG_GETARG_FULLTRANSACTIONID(0);
191+
StringInfoData buf;
192+
193+
pq_begintypsend(&buf);
194+
pq_sendint64(&buf, (uint64) U64FromFullTransactionId(arg1));
195+
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
196+
}
197+
198+
Datum
199+
xid8eq(PG_FUNCTION_ARGS)
200+
{
201+
FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
202+
FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
203+
204+
PG_RETURN_BOOL(FullTransactionIdEquals(fxid1, fxid2));
205+
}
206+
207+
Datum
208+
xid8ne(PG_FUNCTION_ARGS)
209+
{
210+
FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
211+
FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
212+
213+
PG_RETURN_BOOL(!FullTransactionIdEquals(fxid1, fxid2));
214+
}
215+
216+
Datum
217+
xid8lt(PG_FUNCTION_ARGS)
218+
{
219+
FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
220+
FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
221+
222+
PG_RETURN_BOOL(FullTransactionIdPrecedes(fxid1, fxid2));
223+
}
224+
225+
Datum
226+
xid8gt(PG_FUNCTION_ARGS)
227+
{
228+
FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
229+
FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
230+
231+
PG_RETURN_BOOL(FullTransactionIdFollows(fxid1, fxid2));
232+
}
233+
234+
Datum
235+
xid8le(PG_FUNCTION_ARGS)
236+
{
237+
FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
238+
FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
239+
240+
PG_RETURN_BOOL(FullTransactionIdPrecedesOrEquals(fxid1, fxid2));
241+
}
242+
243+
Datum
244+
xid8ge(PG_FUNCTION_ARGS)
245+
{
246+
FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
247+
FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
248+
249+
PG_RETURN_BOOL(FullTransactionIdFollowsOrEquals(fxid1, fxid2));
250+
}
251+
252+
Datum
253+
xid8cmp(PG_FUNCTION_ARGS)
254+
{
255+
FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0);
256+
FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1);
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+
150266
/*****************************************************************************
151267
* COMMAND IDENTIFIER ROUTINES *
152268
*****************************************************************************/

src/fe_utils/print.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3509,6 +3509,7 @@ column_type_alignment(Oid ftype)
35093509
case NUMERICOID:
35103510
case OIDOID:
35113511
case XIDOID:
3512+
case XID8OID:
35123513
case CIDOID:
35133514
case CASHOID:
35143515
align = 'r';

src/include/access/transam.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@
4747
#define EpochFromFullTransactionId(x) ((uint32) ((x).value >> 32))
4848
#define XidFromFullTransactionId(x) ((uint32) (x).value)
4949
#define U64FromFullTransactionId(x) ((x).value)
50+
#define FullTransactionIdEquals(a, b) ((a).value == (b).value)
5051
#define FullTransactionIdPrecedes(a, b) ((a).value < (b).value)
52+
#define FullTransactionIdPrecedesOrEquals(a, b) ((a).value <= (b).value)
53+
#define FullTransactionIdFollows(a, b) ((a).value > (b).value)
54+
#define FullTransactionIdFollowsOrEquals(a, b) ((a).value >= (b).value)
5155
#define FullTransactionIdIsValid(x) TransactionIdIsValid(XidFromFullTransactionId(x))
5256
#define InvalidFullTransactionId FullTransactionIdFromEpochAndXid(0, InvalidTransactionId)
5357

@@ -71,6 +75,16 @@ FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
7175
return result;
7276
}
7377

78+
static inline FullTransactionId
79+
FullTransactionIdFromU64(uint64 value)
80+
{
81+
FullTransactionId result;
82+
83+
result.value = value;
84+
85+
return result;
86+
}
87+
7488
/* advance a transaction ID variable, handling wraparound correctly */
7589
#define TransactionIdAdvance(dest) \
7690
do { \

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 202004022
56+
#define CATALOG_VERSION_NO 202004061
5757

5858
#endif

src/include/catalog/pg_amop.dat

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,24 @@
180180
{ amopfamily => 'btree/oid_ops', amoplefttype => 'oid', amoprighttype => 'oid',
181181
amopstrategy => '5', amopopr => '>(oid,oid)', amopmethod => 'btree' },
182182

183+
# btree xid8_ops
184+
185+
{ amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8',
186+
amoprighttype => 'xid8', amopstrategy => '1', amopopr => '<(xid8,xid8)',
187+
amopmethod => 'btree' },
188+
{ amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8',
189+
amoprighttype => 'xid8', amopstrategy => '2', amopopr => '<=(xid8,xid8)',
190+
amopmethod => 'btree' },
191+
{ amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8',
192+
amoprighttype => 'xid8', amopstrategy => '3', amopopr => '=(xid8,xid8)',
193+
amopmethod => 'btree' },
194+
{ amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8',
195+
amoprighttype => 'xid8', amopstrategy => '4', amopopr => '>=(xid8,xid8)',
196+
amopmethod => 'btree' },
197+
{ amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8',
198+
amoprighttype => 'xid8', amopstrategy => '5', amopopr => '>(xid8,xid8)',
199+
amopmethod => 'btree' },
200+
183201
# btree tid_ops
184202

185203
{ amopfamily => 'btree/tid_ops', amoplefttype => 'tid', amoprighttype => 'tid',
@@ -1009,6 +1027,10 @@
10091027
{ amopfamily => 'hash/xid_ops', amoplefttype => 'xid', amoprighttype => 'xid',
10101028
amopstrategy => '1', amopopr => '=(xid,xid)', amopmethod => 'hash' },
10111029

1030+
# xid8_ops
1031+
{ amopfamily => 'hash/xid8_ops', amoplefttype => 'xid8', amoprighttype => 'xid8',
1032+
amopstrategy => '1', amopopr => '=(xid8,xid8)', amopmethod => 'hash' },
1033+
10121034
# cid_ops
10131035
{ amopfamily => 'hash/cid_ops', amoplefttype => 'cid', amoprighttype => 'cid',
10141036
amopstrategy => '1', amopopr => '=(cid,cid)', amopmethod => 'hash' },

src/include/catalog/pg_amproc.dat

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,10 @@
287287
amprocrighttype => 'anyrange', amprocnum => '1', amproc => 'range_cmp' },
288288
{ amprocfamily => 'btree/jsonb_ops', amproclefttype => 'jsonb',
289289
amprocrighttype => 'jsonb', amprocnum => '1', amproc => 'jsonb_cmp' },
290+
{ amprocfamily => 'btree/xid8_ops', amproclefttype => 'xid8',
291+
amprocrighttype => 'xid8', amprocnum => '1', amproc => 'xid8cmp' },
292+
{ amprocfamily => 'btree/xid8_ops', amproclefttype => 'xid8',
293+
amprocrighttype => 'xid8', amprocnum => '4', amproc => 'btequalimage' },
290294

291295
# hash
292296
{ amprocfamily => 'hash/bpchar_ops', amproclefttype => 'bpchar',
@@ -399,6 +403,10 @@
399403
amprocrighttype => 'xid', amprocnum => '1', amproc => 'hashint4' },
400404
{ amprocfamily => 'hash/xid_ops', amproclefttype => 'xid',
401405
amprocrighttype => 'xid', amprocnum => '2', amproc => 'hashint4extended' },
406+
{ amprocfamily => 'hash/xid8_ops', amproclefttype => 'xid8',
407+
amprocrighttype => 'xid8', amprocnum => '1', amproc => 'hashint8' },
408+
{ amprocfamily => 'hash/xid8_ops', amproclefttype => 'xid8',
409+
amprocrighttype => 'xid8', amprocnum => '2', amproc => 'hashint8extended' },
402410
{ amprocfamily => 'hash/cid_ops', amproclefttype => 'cid',
403411
amprocrighttype => 'cid', amprocnum => '1', amproc => 'hashint4' },
404412
{ amprocfamily => 'hash/cid_ops', amproclefttype => 'cid',

src/include/catalog/pg_cast.dat

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@
9393
{ castsource => 'bool', casttarget => 'int4', castfunc => 'int4(bool)',
9494
castcontext => 'e', castmethod => 'f' },
9595

96+
# Allow explicit coercions between xid8 and xid
97+
{ castsource => 'xid8', casttarget => 'xid', castfunc => 'xid(xid8)',
98+
castcontext => 'e', castmethod => 'f' },
99+
96100
# OID category: allow implicit conversion from any integral type (including
97101
# int8, to support OID literals > 2G) to OID, as well as assignment coercion
98102
# from OID to int4 or int8. Similarly for each OID-alias type. Also allow

src/include/catalog/pg_opclass.dat

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@
168168
opcintype => 'tid' },
169169
{ opcmethod => 'hash', opcname => 'xid_ops', opcfamily => 'hash/xid_ops',
170170
opcintype => 'xid' },
171+
{ opcmethod => 'hash', opcname => 'xid8_ops', opcfamily => 'hash/xid8_ops',
172+
opcintype => 'xid8' },
173+
{ opcmethod => 'btree', opcname => 'xid8_ops', opcfamily => 'btree/xid8_ops',
174+
opcintype => 'xid8' },
171175
{ opcmethod => 'hash', opcname => 'cid_ops', opcfamily => 'hash/cid_ops',
172176
opcintype => 'cid' },
173177
{ opcmethod => 'hash', opcname => 'tid_ops', opcfamily => 'hash/tid_ops',

0 commit comments

Comments
 (0)