diff options
-rw-r--r-- | doc/src/sgml/datatype.sgml | 7 | ||||
-rw-r--r-- | src/backend/access/hash/hashvalidate.c | 3 | ||||
-rw-r--r-- | src/backend/utils/adt/xid.c | 116 | ||||
-rw-r--r-- | src/fe_utils/print.c | 1 | ||||
-rw-r--r-- | src/include/access/transam.h | 14 | ||||
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/pg_amop.dat | 22 | ||||
-rw-r--r-- | src/include/catalog/pg_amproc.dat | 8 | ||||
-rw-r--r-- | src/include/catalog/pg_cast.dat | 4 | ||||
-rw-r--r-- | src/include/catalog/pg_opclass.dat | 4 | ||||
-rw-r--r-- | src/include/catalog/pg_operator.dat | 25 | ||||
-rw-r--r-- | src/include/catalog/pg_opfamily.dat | 4 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.dat | 36 | ||||
-rw-r--r-- | src/include/catalog/pg_type.dat | 4 | ||||
-rw-r--r-- | src/include/utils/xid8.h | 22 | ||||
-rw-r--r-- | src/test/regress/expected/opr_sanity.out | 7 | ||||
-rw-r--r-- | src/test/regress/expected/xid.out | 136 | ||||
-rw-r--r-- | src/test/regress/parallel_schedule | 2 | ||||
-rw-r--r-- | src/test/regress/serial_schedule | 1 | ||||
-rw-r--r-- | src/test/regress/sql/xid.sql | 48 |
20 files changed, 464 insertions, 2 deletions
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index 03971822c29..89f3a7c1196 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -4517,6 +4517,10 @@ INSERT INTO mytable VALUES(-1); -- fails </indexterm> <indexterm zone="datatype-oid"> + <primary>xid8</primary> + </indexterm> + + <indexterm zone="datatype-oid"> <primary>cid</primary> </indexterm> @@ -4719,6 +4723,9 @@ SELECT * FROM pg_attribute Another identifier type used by the system is <type>xid</type>, or transaction (abbreviated <abbrev>xact</abbrev>) identifier. This is the data type of the system columns <structfield>xmin</structfield> and <structfield>xmax</structfield>. Transaction identifiers are 32-bit quantities. + In some contexts, a 64-bit variant <type>xid8</type> is used. Unlike + <type>xid</type> values, <type>xid8</type> values increase strictly + monotonically and cannot be reused in the lifetime of a database cluster. </para> <para> diff --git a/src/backend/access/hash/hashvalidate.c b/src/backend/access/hash/hashvalidate.c index 7b08ed53543..b3d1367fecb 100644 --- a/src/backend/access/hash/hashvalidate.c +++ b/src/backend/access/hash/hashvalidate.c @@ -317,6 +317,9 @@ check_hash_func_signature(Oid funcid, int16 amprocnum, Oid argtype) (argtype == DATEOID || argtype == XIDOID || argtype == CIDOID)) /* okay, allowed use of hashint4() */ ; + else if ((funcid == F_HASHINT8 || funcid == F_HASHINT8EXTENDED) && + (argtype == XID8OID)) + /* okay, allowed use of hashint8() */ ; else if ((funcid == F_TIMESTAMP_HASH || funcid == F_TIMESTAMP_HASH_EXTENDED) && argtype == TIMESTAMPTZOID) diff --git a/src/backend/utils/adt/xid.c b/src/backend/utils/adt/xid.c index db6fc9dd6b8..20389aff1d1 100644 --- a/src/backend/utils/adt/xid.c +++ b/src/backend/utils/adt/xid.c @@ -21,6 +21,7 @@ #include "access/xact.h" #include "libpq/pqformat.h" #include "utils/builtins.h" +#include "utils/xid8.h" #define PG_GETARG_TRANSACTIONID(n) DatumGetTransactionId(PG_GETARG_DATUM(n)) #define PG_RETURN_TRANSACTIONID(x) return TransactionIdGetDatum(x) @@ -147,6 +148,121 @@ xidComparator(const void *arg1, const void *arg2) return 0; } +Datum +xid8toxid(PG_FUNCTION_ARGS) +{ + FullTransactionId fxid = PG_GETARG_FULLTRANSACTIONID(0); + + PG_RETURN_TRANSACTIONID(XidFromFullTransactionId(fxid)); +} + +Datum +xid8in(PG_FUNCTION_ARGS) +{ + char *str = PG_GETARG_CSTRING(0); + + PG_RETURN_FULLTRANSACTIONID(FullTransactionIdFromU64(pg_strtouint64(str, NULL, 0))); +} + +Datum +xid8out(PG_FUNCTION_ARGS) +{ + FullTransactionId fxid = PG_GETARG_FULLTRANSACTIONID(0); + char *result = (char *) palloc(21); + + snprintf(result, 21, UINT64_FORMAT, U64FromFullTransactionId(fxid)); + PG_RETURN_CSTRING(result); +} + +Datum +xid8recv(PG_FUNCTION_ARGS) +{ + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + uint64 value; + + value = (uint64) pq_getmsgint64(buf); + PG_RETURN_FULLTRANSACTIONID(FullTransactionIdFromU64(value)); +} + +Datum +xid8send(PG_FUNCTION_ARGS) +{ + FullTransactionId arg1 = PG_GETARG_FULLTRANSACTIONID(0); + StringInfoData buf; + + pq_begintypsend(&buf); + pq_sendint64(&buf, (uint64) U64FromFullTransactionId(arg1)); + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); +} + +Datum +xid8eq(PG_FUNCTION_ARGS) +{ + FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0); + FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1); + + PG_RETURN_BOOL(FullTransactionIdEquals(fxid1, fxid2)); +} + +Datum +xid8ne(PG_FUNCTION_ARGS) +{ + FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0); + FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1); + + PG_RETURN_BOOL(!FullTransactionIdEquals(fxid1, fxid2)); +} + +Datum +xid8lt(PG_FUNCTION_ARGS) +{ + FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0); + FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1); + + PG_RETURN_BOOL(FullTransactionIdPrecedes(fxid1, fxid2)); +} + +Datum +xid8gt(PG_FUNCTION_ARGS) +{ + FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0); + FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1); + + PG_RETURN_BOOL(FullTransactionIdFollows(fxid1, fxid2)); +} + +Datum +xid8le(PG_FUNCTION_ARGS) +{ + FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0); + FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1); + + PG_RETURN_BOOL(FullTransactionIdPrecedesOrEquals(fxid1, fxid2)); +} + +Datum +xid8ge(PG_FUNCTION_ARGS) +{ + FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0); + FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1); + + PG_RETURN_BOOL(FullTransactionIdFollowsOrEquals(fxid1, fxid2)); +} + +Datum +xid8cmp(PG_FUNCTION_ARGS) +{ + FullTransactionId fxid1 = PG_GETARG_FULLTRANSACTIONID(0); + FullTransactionId fxid2 = PG_GETARG_FULLTRANSACTIONID(1); + + if (FullTransactionIdFollows(fxid1, fxid2)) + PG_RETURN_INT32(1); + else if (FullTransactionIdEquals(fxid1, fxid2)) + PG_RETURN_INT32(0); + else + PG_RETURN_INT32(-1); +} + /***************************************************************************** * COMMAND IDENTIFIER ROUTINES * *****************************************************************************/ diff --git a/src/fe_utils/print.c b/src/fe_utils/print.c index 06096cc86cb..66a50f183f5 100644 --- a/src/fe_utils/print.c +++ b/src/fe_utils/print.c @@ -3509,6 +3509,7 @@ column_type_alignment(Oid ftype) case NUMERICOID: case OIDOID: case XIDOID: + case XID8OID: case CIDOID: case CASHOID: align = 'r'; diff --git a/src/include/access/transam.h b/src/include/access/transam.h index 6a947b958b0..9a808f64ebe 100644 --- a/src/include/access/transam.h +++ b/src/include/access/transam.h @@ -47,7 +47,11 @@ #define EpochFromFullTransactionId(x) ((uint32) ((x).value >> 32)) #define XidFromFullTransactionId(x) ((uint32) (x).value) #define U64FromFullTransactionId(x) ((x).value) +#define FullTransactionIdEquals(a, b) ((a).value == (b).value) #define FullTransactionIdPrecedes(a, b) ((a).value < (b).value) +#define FullTransactionIdPrecedesOrEquals(a, b) ((a).value <= (b).value) +#define FullTransactionIdFollows(a, b) ((a).value > (b).value) +#define FullTransactionIdFollowsOrEquals(a, b) ((a).value >= (b).value) #define FullTransactionIdIsValid(x) TransactionIdIsValid(XidFromFullTransactionId(x)) #define InvalidFullTransactionId FullTransactionIdFromEpochAndXid(0, InvalidTransactionId) @@ -71,6 +75,16 @@ FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid) return result; } +static inline FullTransactionId +FullTransactionIdFromU64(uint64 value) +{ + FullTransactionId result; + + result.value = value; + + return result; +} + /* advance a transaction ID variable, handling wraparound correctly */ #define TransactionIdAdvance(dest) \ do { \ diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 6d91fa2bde3..4201790ec48 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202004022 +#define CATALOG_VERSION_NO 202004061 #endif diff --git a/src/include/catalog/pg_amop.dat b/src/include/catalog/pg_amop.dat index 11aaa519c8b..b5dfaad9ec0 100644 --- a/src/include/catalog/pg_amop.dat +++ b/src/include/catalog/pg_amop.dat @@ -180,6 +180,24 @@ { amopfamily => 'btree/oid_ops', amoplefttype => 'oid', amoprighttype => 'oid', amopstrategy => '5', amopopr => '>(oid,oid)', amopmethod => 'btree' }, +# btree xid8_ops + +{ amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8', + amoprighttype => 'xid8', amopstrategy => '1', amopopr => '<(xid8,xid8)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8', + amoprighttype => 'xid8', amopstrategy => '2', amopopr => '<=(xid8,xid8)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8', + amoprighttype => 'xid8', amopstrategy => '3', amopopr => '=(xid8,xid8)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8', + amoprighttype => 'xid8', amopstrategy => '4', amopopr => '>=(xid8,xid8)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8', + amoprighttype => 'xid8', amopstrategy => '5', amopopr => '>(xid8,xid8)', + amopmethod => 'btree' }, + # btree tid_ops { amopfamily => 'btree/tid_ops', amoplefttype => 'tid', amoprighttype => 'tid', @@ -1009,6 +1027,10 @@ { amopfamily => 'hash/xid_ops', amoplefttype => 'xid', amoprighttype => 'xid', amopstrategy => '1', amopopr => '=(xid,xid)', amopmethod => 'hash' }, +# xid8_ops +{ amopfamily => 'hash/xid8_ops', amoplefttype => 'xid8', amoprighttype => 'xid8', + amopstrategy => '1', amopopr => '=(xid8,xid8)', amopmethod => 'hash' }, + # cid_ops { amopfamily => 'hash/cid_ops', amoplefttype => 'cid', amoprighttype => 'cid', amopstrategy => '1', amopopr => '=(cid,cid)', amopmethod => 'hash' }, diff --git a/src/include/catalog/pg_amproc.dat b/src/include/catalog/pg_amproc.dat index cef63b2a716..37b580883fc 100644 --- a/src/include/catalog/pg_amproc.dat +++ b/src/include/catalog/pg_amproc.dat @@ -287,6 +287,10 @@ amprocrighttype => 'anyrange', amprocnum => '1', amproc => 'range_cmp' }, { amprocfamily => 'btree/jsonb_ops', amproclefttype => 'jsonb', amprocrighttype => 'jsonb', amprocnum => '1', amproc => 'jsonb_cmp' }, +{ amprocfamily => 'btree/xid8_ops', amproclefttype => 'xid8', + amprocrighttype => 'xid8', amprocnum => '1', amproc => 'xid8cmp' }, +{ amprocfamily => 'btree/xid8_ops', amproclefttype => 'xid8', + amprocrighttype => 'xid8', amprocnum => '4', amproc => 'btequalimage' }, # hash { amprocfamily => 'hash/bpchar_ops', amproclefttype => 'bpchar', @@ -399,6 +403,10 @@ amprocrighttype => 'xid', amprocnum => '1', amproc => 'hashint4' }, { amprocfamily => 'hash/xid_ops', amproclefttype => 'xid', amprocrighttype => 'xid', amprocnum => '2', amproc => 'hashint4extended' }, +{ amprocfamily => 'hash/xid8_ops', amproclefttype => 'xid8', + amprocrighttype => 'xid8', amprocnum => '1', amproc => 'hashint8' }, +{ amprocfamily => 'hash/xid8_ops', amproclefttype => 'xid8', + amprocrighttype => 'xid8', amprocnum => '2', amproc => 'hashint8extended' }, { amprocfamily => 'hash/cid_ops', amproclefttype => 'cid', amprocrighttype => 'cid', amprocnum => '1', amproc => 'hashint4' }, { amprocfamily => 'hash/cid_ops', amproclefttype => 'cid', diff --git a/src/include/catalog/pg_cast.dat b/src/include/catalog/pg_cast.dat index 01c5328dddb..5a58f50fbb2 100644 --- a/src/include/catalog/pg_cast.dat +++ b/src/include/catalog/pg_cast.dat @@ -93,6 +93,10 @@ { castsource => 'bool', casttarget => 'int4', castfunc => 'int4(bool)', castcontext => 'e', castmethod => 'f' }, +# Allow explicit coercions between xid8 and xid +{ castsource => 'xid8', casttarget => 'xid', castfunc => 'xid(xid8)', + castcontext => 'e', castmethod => 'f' }, + # OID category: allow implicit conversion from any integral type (including # int8, to support OID literals > 2G) to OID, as well as assignment coercion # from OID to int4 or int8. Similarly for each OID-alias type. Also allow diff --git a/src/include/catalog/pg_opclass.dat b/src/include/catalog/pg_opclass.dat index ab2f50c9eb3..f2342bb328c 100644 --- a/src/include/catalog/pg_opclass.dat +++ b/src/include/catalog/pg_opclass.dat @@ -168,6 +168,10 @@ opcintype => 'tid' }, { opcmethod => 'hash', opcname => 'xid_ops', opcfamily => 'hash/xid_ops', opcintype => 'xid' }, +{ opcmethod => 'hash', opcname => 'xid8_ops', opcfamily => 'hash/xid8_ops', + opcintype => 'xid8' }, +{ opcmethod => 'btree', opcname => 'xid8_ops', opcfamily => 'btree/xid8_ops', + opcintype => 'xid8' }, { opcmethod => 'hash', opcname => 'cid_ops', opcfamily => 'hash/cid_ops', opcintype => 'cid' }, { opcmethod => 'hash', opcname => 'tid_ops', opcfamily => 'hash/tid_ops', diff --git a/src/include/catalog/pg_operator.dat b/src/include/catalog/pg_operator.dat index 65c7fedf237..00ada7e48fc 100644 --- a/src/include/catalog/pg_operator.dat +++ b/src/include/catalog/pg_operator.dat @@ -193,6 +193,31 @@ oprname => '<>', oprleft => 'xid', oprright => 'int4', oprresult => 'bool', oprnegate => '=(xid,int4)', oprcode => 'xidneqint4', oprrest => 'neqsel', oprjoin => 'neqjoinsel' }, +{ oid => '9418', descr => 'equal', + oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'xid8', + oprright => 'xid8', oprresult => 'bool', oprcom => '=(xid8,xid8)', + oprnegate => '<>(xid8,xid8)', oprcode => 'xid8eq', oprrest => 'eqsel', + oprjoin => 'eqjoinsel' }, +{ oid => '9422', descr => 'not equal', + oprname => '<>', oprleft => 'xid8', oprright => 'xid8', + oprresult => 'bool', oprcom => '<>(xid8,xid8)', oprnegate => '=(xid8,xid8)', + oprcode => 'xid8ne', oprrest => 'neqsel', oprjoin => 'neqjoinsel' }, +{ oid => '9432', descr => 'less than', + oprname => '<', oprleft => 'xid8', oprright => 'xid8', oprresult => 'bool', + oprcom => '>(xid8,xid8)', oprnegate => '>=(xid8,xid8)', oprcode => 'xid8lt', + oprrest => 'scalarltsel', oprjoin => 'scalarltjoinsel' }, +{ oid => '9433', descr => 'greater than', + oprname => '>', oprleft => 'xid8', oprright => 'xid8', oprresult => 'bool', + oprcom => '<(xid8,xid8)', oprnegate => '<=(xid8,xid8)', oprcode => 'xid8gt', + oprrest => 'scalargtsel', oprjoin => 'scalargtjoinsel' }, +{ oid => '9434', descr => 'less than or equal', + oprname => '<=', oprleft => 'xid8', oprright => 'xid8', oprresult => 'bool', + oprcom => '>=(xid8,xid8)', oprnegate => '>(xid8,xid8)', oprcode => 'xid8le', + oprrest => 'scalarlesel', oprjoin => 'scalarlejoinsel' }, +{ oid => '9435', descr => 'greater than or equal', + oprname => '>=', oprleft => 'xid8', oprright => 'xid8', oprresult => 'bool', + oprcom => '<=(xid8,xid8)', oprnegate => '<(xid8,xid8)', oprcode => 'xid8ge', + oprrest => 'scalargesel', oprjoin => 'scalargejoinsel' }, { oid => '388', descr => 'factorial', oprname => '!', oprkind => 'r', oprleft => 'int8', oprright => '0', oprresult => 'numeric', oprcode => 'numeric_fac' }, diff --git a/src/include/catalog/pg_opfamily.dat b/src/include/catalog/pg_opfamily.dat index 26227df2165..4004138d778 100644 --- a/src/include/catalog/pg_opfamily.dat +++ b/src/include/catalog/pg_opfamily.dat @@ -110,6 +110,10 @@ opfmethod => 'btree', opfname => 'tid_ops' }, { oid => '2225', opfmethod => 'hash', opfname => 'xid_ops' }, +{ oid => '8164', + opfmethod => 'hash', opfname => 'xid8_ops' }, +{ oid => '9322', + opfmethod => 'btree', opfname => 'xid8_ops' }, { oid => '2226', opfmethod => 'hash', opfname => 'cid_ops' }, { oid => '2227', diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index a649e44d089..6be7e4f1571 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -112,6 +112,18 @@ { oid => '51', descr => 'I/O', proname => 'xidout', prorettype => 'cstring', proargtypes => 'xid', prosrc => 'xidout' }, +{ oid => '9420', descr => 'I/O', + proname => 'xid8in', prorettype => 'xid8', proargtypes => 'cstring', + prosrc => 'xid8in' }, +{ oid => '9554', descr => 'I/O', + proname => 'xid8out', prorettype => 'cstring', proargtypes => 'xid8', + prosrc => 'xid8out' }, +{ oid => '9555', descr => 'I/O', + proname => 'xid8recv', prorettype => 'xid8', proargtypes => 'internal', + prosrc => 'xid8recv' }, +{ oid => '9556', descr => 'I/O', + proname => 'xid8send', prorettype => 'bytea', proargtypes => 'xid8', + prosrc => 'xid8send' }, { oid => '52', descr => 'I/O', proname => 'cidin', prorettype => 'cid', proargtypes => 'cstring', prosrc => 'cidin' }, @@ -163,6 +175,30 @@ { oid => '3308', proname => 'xidneq', proleakproof => 't', prorettype => 'bool', proargtypes => 'xid xid', prosrc => 'xidneq' }, +{ oid => '9557', + proname => 'xid8eq', proleakproof => 't', prorettype => 'bool', + proargtypes => 'xid8 xid8', prosrc => 'xid8eq' }, +{ oid => '9558', + proname => 'xid8ne', proleakproof => 't', prorettype => 'bool', + proargtypes => 'xid8 xid8', prosrc => 'xid8ne' }, +{ oid => '8295', + proname => 'xid8lt', proleakproof => 't', prorettype => 'bool', + proargtypes => 'xid8 xid8', prosrc => 'xid8lt' }, +{ oid => '8296', + proname => 'xid8gt', proleakproof => 't', prorettype => 'bool', + proargtypes => 'xid8 xid8', prosrc => 'xid8gt' }, +{ oid => '8297', + proname => 'xid8le', proleakproof => 't', prorettype => 'bool', + proargtypes => 'xid8 xid8', prosrc => 'xid8le' }, +{ oid => '8298', + proname => 'xid8ge', proleakproof => 't', prorettype => 'bool', + proargtypes => 'xid8 xid8', prosrc => 'xid8ge' }, +{ oid => '9912', descr => 'less-equal-greater', + proname => 'xid8cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'xid8 xid8', prosrc => 'xid8cmp' }, +{ oid => '9421', descr => 'convert xid8 to xid', + proname => 'xid', prorettype => 'xid', proargtypes => 'xid8', + prosrc => 'xid8toxid' }, { oid => '69', proname => 'cideq', proleakproof => 't', prorettype => 'bool', proargtypes => 'cid cid', prosrc => 'cideq' }, diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat index 2e6110e3f2c..a1f441b8daa 100644 --- a/src/include/catalog/pg_type.dat +++ b/src/include/catalog/pg_type.dat @@ -177,6 +177,10 @@ typtype => 'p', typcategory => 'P', typinput => 'pg_ddl_command_in', typoutput => 'pg_ddl_command_out', typreceive => 'pg_ddl_command_recv', typsend => 'pg_ddl_command_send', typalign => 'ALIGNOF_POINTER' }, +{ oid => '9419', array_type_oid => '271', descr => 'full transaction id', + typname => 'xid8', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', + typcategory => 'U', typinput => 'xid8in', typoutput => 'xid8out', + typreceive => 'xid8recv', typsend => 'xid8send', typalign => 'd' }, # OIDS 600 - 699 diff --git a/src/include/utils/xid8.h b/src/include/utils/xid8.h new file mode 100644 index 00000000000..288e62de9c3 --- /dev/null +++ b/src/include/utils/xid8.h @@ -0,0 +1,22 @@ +/*------------------------------------------------------------------------- + * + * xid8.h + * Header file for the "xid8" ADT. + * + * Copyright (c) 2020, PostgreSQL Global Development Group + * + * src/include/utils/xid8.h + * + *------------------------------------------------------------------------- + */ +#ifndef XID8_H +#define XID8_H + +#include "access/transam.h" + +#define DatumGetFullTransactionId(X) (FullTransactionIdFromU64(DatumGetUInt64(X))) +#define FullTransactionIdGetDatum(X) (UInt64GetDatum(U64FromFullTransactionId(X))) +#define PG_GETARG_FULLTRANSACTIONID(X) DatumGetFullTransactionId(PG_GETARG_DATUM(X)) +#define PG_RETURN_FULLTRANSACTIONID(X) return FullTransactionIdGetDatum(X) + +#endif /* XID8_H */ diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index 2efd7d7ec74..0c03afe53d2 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -832,6 +832,13 @@ macaddr8_gt(macaddr8,macaddr8) macaddr8_ge(macaddr8,macaddr8) macaddr8_ne(macaddr8,macaddr8) macaddr8_cmp(macaddr8,macaddr8) +xid8lt(xid8,xid8) +xid8gt(xid8,xid8) +xid8le(xid8,xid8) +xid8ge(xid8,xid8) +xid8eq(xid8,xid8) +xid8ne(xid8,xid8) +xid8cmp(xid8,xid8) -- restore normal output mode \a\t -- List of functions used by libpq's fe-lobj.c diff --git a/src/test/regress/expected/xid.out b/src/test/regress/expected/xid.out new file mode 100644 index 00000000000..e9e1fa82591 --- /dev/null +++ b/src/test/regress/expected/xid.out @@ -0,0 +1,136 @@ +-- xid and xid8 +-- values in range, in octal, decimal, hex +select '010'::xid, + '42'::xid, + '0xffffffff'::xid, + '-1'::xid, + '010'::xid8, + '42'::xid8, + '0xffffffffffffffff'::xid8, + '-1'::xid8; + xid | xid | xid | xid | xid8 | xid8 | xid8 | xid8 +-----+-----+------------+------------+------+------+----------------------+---------------------- + 8 | 42 | 4294967295 | 4294967295 | 8 | 42 | 18446744073709551615 | 18446744073709551615 +(1 row) + +-- garbage values are not yet rejected (perhaps they should be) +select ''::xid; + xid +----- + 0 +(1 row) + +select 'asdf'::xid; + xid +----- + 0 +(1 row) + +select ''::xid8; + xid8 +------ + 0 +(1 row) + +select 'asdf'::xid8; + xid8 +------ + 0 +(1 row) + +-- equality +select '1'::xid = '1'::xid; + ?column? +---------- + t +(1 row) + +select '1'::xid != '1'::xid; + ?column? +---------- + f +(1 row) + +select '1'::xid8 = '1'::xid8; + ?column? +---------- + t +(1 row) + +select '1'::xid8 != '1'::xid8; + ?column? +---------- + f +(1 row) + +-- conversion +select '1'::xid = '1'::xid8::xid; + ?column? +---------- + t +(1 row) + +select '1'::xid != '1'::xid8::xid; + ?column? +---------- + f +(1 row) + +-- we don't want relational operators for xid, due to use of modular arithmetic +select '1'::xid < '2'::xid; +ERROR: operator does not exist: xid < xid +LINE 1: select '1'::xid < '2'::xid; + ^ +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. +select '1'::xid <= '2'::xid; +ERROR: operator does not exist: xid <= xid +LINE 1: select '1'::xid <= '2'::xid; + ^ +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. +select '1'::xid > '2'::xid; +ERROR: operator does not exist: xid > xid +LINE 1: select '1'::xid > '2'::xid; + ^ +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. +select '1'::xid >= '2'::xid; +ERROR: operator does not exist: xid >= xid +LINE 1: select '1'::xid >= '2'::xid; + ^ +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. +-- we want them for xid8 though +select '1'::xid8 < '2'::xid8, '2'::xid8 < '2'::xid8, '2'::xid8 < '1'::xid8; + ?column? | ?column? | ?column? +----------+----------+---------- + t | f | f +(1 row) + +select '1'::xid8 <= '2'::xid8, '2'::xid8 <= '2'::xid8, '2'::xid8 <= '1'::xid8; + ?column? | ?column? | ?column? +----------+----------+---------- + t | t | f +(1 row) + +select '1'::xid8 > '2'::xid8, '2'::xid8 > '2'::xid8, '2'::xid8 > '1'::xid8; + ?column? | ?column? | ?column? +----------+----------+---------- + f | f | t +(1 row) + +select '1'::xid8 >= '2'::xid8, '2'::xid8 >= '2'::xid8, '2'::xid8 >= '1'::xid8; + ?column? | ?column? | ?column? +----------+----------+---------- + f | t | t +(1 row) + +-- we also have a 3way compare for btrees +select xid8cmp('1', '2'), xid8cmp('2', '2'), xid8cmp('2', '1'); + xid8cmp | xid8cmp | xid8cmp +---------+---------+--------- + -1 | 0 | 1 +(1 row) + +-- xid8 has btree and hash opclasses +create table xid8_t1 (x xid8); +create index on xid8_t1 using btree(x); +create index on xid8_t1 using hash(x); +drop table xid8_t1; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index a741e89616a..95f1925072b 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -20,7 +20,7 @@ test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeri # strings depends on char, varchar and text # numerology depends on int2, int4, int8, float4, float8 # ---------- -test: strings numerology point lseg line box path polygon circle date time timetz timestamp timestamptz interval inet macaddr macaddr8 tstypes +test: strings numerology point lseg line box path polygon circle date time timetz timestamp timestamptz interval inet macaddr macaddr8 tstypes xid # ---------- # Another group of parallel tests diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 1a6821ca46b..8ba41362202 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -10,6 +10,7 @@ test: int2 test: int4 test: int8 test: oid +test: xid test: float4 test: float8 test: bit diff --git a/src/test/regress/sql/xid.sql b/src/test/regress/sql/xid.sql new file mode 100644 index 00000000000..a4fbca51766 --- /dev/null +++ b/src/test/regress/sql/xid.sql @@ -0,0 +1,48 @@ +-- xid and xid8 + +-- values in range, in octal, decimal, hex +select '010'::xid, + '42'::xid, + '0xffffffff'::xid, + '-1'::xid, + '010'::xid8, + '42'::xid8, + '0xffffffffffffffff'::xid8, + '-1'::xid8; + +-- garbage values are not yet rejected (perhaps they should be) +select ''::xid; +select 'asdf'::xid; +select ''::xid8; +select 'asdf'::xid8; + +-- equality +select '1'::xid = '1'::xid; +select '1'::xid != '1'::xid; +select '1'::xid8 = '1'::xid8; +select '1'::xid8 != '1'::xid8; + +-- conversion +select '1'::xid = '1'::xid8::xid; +select '1'::xid != '1'::xid8::xid; + +-- we don't want relational operators for xid, due to use of modular arithmetic +select '1'::xid < '2'::xid; +select '1'::xid <= '2'::xid; +select '1'::xid > '2'::xid; +select '1'::xid >= '2'::xid; + +-- we want them for xid8 though +select '1'::xid8 < '2'::xid8, '2'::xid8 < '2'::xid8, '2'::xid8 < '1'::xid8; +select '1'::xid8 <= '2'::xid8, '2'::xid8 <= '2'::xid8, '2'::xid8 <= '1'::xid8; +select '1'::xid8 > '2'::xid8, '2'::xid8 > '2'::xid8, '2'::xid8 > '1'::xid8; +select '1'::xid8 >= '2'::xid8, '2'::xid8 >= '2'::xid8, '2'::xid8 >= '1'::xid8; + +-- we also have a 3way compare for btrees +select xid8cmp('1', '2'), xid8cmp('2', '2'), xid8cmp('2', '1'); + +-- xid8 has btree and hash opclasses +create table xid8_t1 (x xid8); +create index on xid8_t1 using btree(x); +create index on xid8_t1 using hash(x); +drop table xid8_t1; |