<primary>oid</primary>
</indexterm>
+ <indexterm zone="datatype-oid">
+ <primary>oid8</primary>
+ </indexterm>
+
<indexterm zone="datatype-oid">
<primary>regclass</primary>
</indexterm>
</para>
<para>
- The <type>oid</type> type itself has few operations beyond comparison.
- It can be cast to integer, however, and then manipulated using the
+ In some contexts, a 64-bit variant <type>oid8</type> can be used.
+ It is implemented as an unsigned eight-byte integer. Unlike its
+ <type>oid</type> counterpart, it can ensure uniqueness in large
+ individual tables.
+ </para>
+
+ <para>
+ The <type>oid</type> and <type>oid8</type> types themselves have
+ few operations beyond comparison.
+ they can be cast to integer, however, and then manipulated using the
standard integer operators. (Beware of possible
signed-versus-unsigned confusion if you do this.)
</para>
Computes the maximum of the non-null input
values. Available for any numeric, string, date/time, or enum type,
as well as <type>bytea</type>, <type>inet</type>, <type>interval</type>,
- <type>money</type>, <type>oid</type>, <type>pg_lsn</type>,
- <type>tid</type>, <type>xid8</type>,
+ <type>money</type>, <type>oid</type>, <type>oid8</type>,
+ <type>pg_lsn</type>, <type>tid</type>, <type>xid8</type>,
and also arrays and composite types containing sortable data types.
</para></entry>
<entry>Yes</entry>
Computes the minimum of the non-null input
values. Available for any numeric, string, date/time, or enum type,
as well as <type>bytea</type>, <type>inet</type>, <type>interval</type>,
- <type>money</type>, <type>oid</type>, <type>pg_lsn</type>,
- <type>tid</type>, <type>xid8</type>,
+ <type>money</type>, <type>oid</type>, <type>oid8</type>,
+ <type>pg_lsn</type>, <type>tid</type>, <type>xid8</type>,
and also arrays and composite types containing sortable data types.
</para></entry>
<entry>Yes</entry>
PG_RETURN_VOID();
}
+Datum
+btoid8cmp(PG_FUNCTION_ARGS)
+{
+ Oid8 a = PG_GETARG_OID8(0);
+ Oid8 b = PG_GETARG_OID8(1);
+
+ if (a > b)
+ PG_RETURN_INT32(A_GREATER_THAN_B);
+ else if (a == b)
+ PG_RETURN_INT32(0);
+ else
+ PG_RETURN_INT32(A_LESS_THAN_B);
+}
+
+static int
+btoid8fastcmp(Datum x, Datum y, SortSupport ssup)
+{
+ Oid8 a = DatumGetObjectId8(x);
+ Oid8 b = DatumGetObjectId8(y);
+
+ if (a > b)
+ return A_GREATER_THAN_B;
+ else if (a == b)
+ return 0;
+ else
+ return A_LESS_THAN_B;
+}
+
+Datum
+btoid8sortsupport(PG_FUNCTION_ARGS)
+{
+ SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
+
+ ssup->comparator = btoid8fastcmp;
+ PG_RETURN_VOID();
+}
+
+static Datum
+oid8_decrement(Relation rel, Datum existing, bool *underflow)
+{
+ Oid8 oexisting = DatumGetObjectId8(existing);
+
+ if (oexisting == InvalidOid8)
+ {
+ /* return value is undefined */
+ *underflow = true;
+ return (Datum) 0;
+ }
+
+ *underflow = false;
+ return ObjectId8GetDatum(oexisting - 1);
+}
+
+static Datum
+oid8_increment(Relation rel, Datum existing, bool *overflow)
+{
+ Oid8 oexisting = DatumGetObjectId8(existing);
+
+ if (oexisting == OID8_MAX)
+ {
+ /* return value is undefined */
+ *overflow = true;
+ return (Datum) 0;
+ }
+
+ *overflow = false;
+ return ObjectId8GetDatum(oexisting + 1);
+}
+
+Datum
+btoid8skipsupport(PG_FUNCTION_ARGS)
+{
+ SkipSupport sksup = (SkipSupport) PG_GETARG_POINTER(0);
+
+ sksup->decrement = oid8_decrement;
+ sksup->increment = oid8_increment;
+ sksup->low_elem = ObjectId8GetDatum(InvalidOid8);
+ sksup->high_elem = ObjectId8GetDatum(OID8_MAX);
+
+ PG_RETURN_VOID();
+}
+
Datum
btoidvectorcmp(PG_FUNCTION_ARGS)
{
F_TEXTIN, F_TEXTOUT},
{"oid", OIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
F_OIDIN, F_OIDOUT},
+ {"oid8", OID8OID, 0, 8, true, TYPALIGN_DOUBLE, TYPSTORAGE_PLAIN, InvalidOid,
+ F_OID8IN, F_OID8OUT},
{"tid", TIDOID, 0, 6, false, TYPALIGN_SHORT, TYPSTORAGE_PLAIN, InvalidOid,
F_TIDIN, F_TIDOUT},
{"xid", XIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
numeric.o \
numutils.o \
oid.o \
+ oid8.o \
oracle_compat.o \
orderedsetaggs.o \
partitionfuncs.o \
PG_RETURN_INT64((int64) arg);
}
+Datum
+oidtooid8(PG_FUNCTION_ARGS)
+{
+ Oid arg = PG_GETARG_OID(0);
+
+ PG_RETURN_OID8((Oid8) arg);
+}
+
/*
* non-persistent numeric series generator
*/
'network_spgist.c',
'numutils.c',
'oid.c',
+ 'oid8.c',
'oracle_compat.c',
'orderedsetaggs.c',
'partitionfuncs.c',
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * oid8.c
+ * Functions for the built-in type Oid8
+ *
+ * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/backend/utils/adt/oid8.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "catalog/pg_type.h"
+#include "libpq/pqformat.h"
+#include "utils/builtins.h"
+
+#define MAXOID8LEN 20
+
+/*****************************************************************************
+ * USER I/O ROUTINES *
+ *****************************************************************************/
+
+Datum
+oid8in(PG_FUNCTION_ARGS)
+{
+ char *s = PG_GETARG_CSTRING(0);
+ Oid8 result;
+
+ result = uint64in_subr(s, NULL, "oid8", fcinfo->context);
+ PG_RETURN_OID8(result);
+}
+
+Datum
+oid8out(PG_FUNCTION_ARGS)
+{
+ Oid8 val = PG_GETARG_OID8(0);
+ char buf[MAXOID8LEN + 1];
+ char *result;
+ int len;
+
+ len = pg_ulltoa_n(val, buf) + 1;
+ buf[len - 1] = '\0';
+
+ /*
+ * Since the length is already known, we do a manual palloc() and memcpy()
+ * to avoid the strlen() call that would otherwise be done in pstrdup().
+ */
+ result = palloc(len);
+ memcpy(result, buf, len);
+ PG_RETURN_CSTRING(result);
+}
+
+/*
+ * oid8recv - converts external binary format to oid8
+ */
+Datum
+oid8recv(PG_FUNCTION_ARGS)
+{
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+
+ PG_RETURN_OID8(pq_getmsgint64(buf));
+}
+
+/*
+ * oid8send - converts oid8 to binary format
+ */
+Datum
+oid8send(PG_FUNCTION_ARGS)
+{
+ Oid8 arg1 = PG_GETARG_OID8(0);
+ StringInfoData buf;
+
+ pq_begintypsend(&buf);
+ pq_sendint64(&buf, arg1);
+ PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+}
+
+/*****************************************************************************
+ * PUBLIC ROUTINES *
+ *****************************************************************************/
+
+Datum
+oid8eq(PG_FUNCTION_ARGS)
+{
+ Oid8 arg1 = PG_GETARG_OID8(0);
+ Oid8 arg2 = PG_GETARG_OID8(1);
+
+ PG_RETURN_BOOL(arg1 == arg2);
+}
+
+Datum
+oid8ne(PG_FUNCTION_ARGS)
+{
+ Oid8 arg1 = PG_GETARG_OID8(0);
+ Oid8 arg2 = PG_GETARG_OID8(1);
+
+ PG_RETURN_BOOL(arg1 != arg2);
+}
+
+Datum
+oid8lt(PG_FUNCTION_ARGS)
+{
+ Oid8 arg1 = PG_GETARG_OID8(0);
+ Oid8 arg2 = PG_GETARG_OID8(1);
+
+ PG_RETURN_BOOL(arg1 < arg2);
+}
+
+Datum
+oid8le(PG_FUNCTION_ARGS)
+{
+ Oid8 arg1 = PG_GETARG_OID8(0);
+ Oid8 arg2 = PG_GETARG_OID8(1);
+
+ PG_RETURN_BOOL(arg1 <= arg2);
+}
+
+Datum
+oid8ge(PG_FUNCTION_ARGS)
+{
+ Oid8 arg1 = PG_GETARG_OID8(0);
+ Oid8 arg2 = PG_GETARG_OID8(1);
+
+ PG_RETURN_BOOL(arg1 >= arg2);
+}
+
+Datum
+oid8gt(PG_FUNCTION_ARGS)
+{
+ Oid8 arg1 = PG_GETARG_OID8(0);
+ Oid8 arg2 = PG_GETARG_OID8(1);
+
+ PG_RETURN_BOOL(arg1 > arg2);
+}
+
+Datum
+hashoid8(PG_FUNCTION_ARGS)
+{
+ return hashint8(fcinfo);
+}
+
+Datum
+hashoid8extended(PG_FUNCTION_ARGS)
+{
+ return hashint8extended(fcinfo);
+}
+
+Datum
+oid8larger(PG_FUNCTION_ARGS)
+{
+ Oid8 arg1 = PG_GETARG_OID8(0);
+ Oid8 arg2 = PG_GETARG_OID8(1);
+
+ PG_RETURN_OID8((arg1 > arg2) ? arg1 : arg2);
+}
+
+Datum
+oid8smaller(PG_FUNCTION_ARGS)
+{
+ Oid8 arg1 = PG_GETARG_OID8(0);
+ Oid8 arg2 = PG_GETARG_OID8(1);
+
+ PG_RETURN_OID8((arg1 < arg2) ? arg1 : arg2);
+}
case FLOAT8OID:
case NUMERICOID:
case OIDOID:
+ case OID8OID:
case XIDOID:
case XID8OID:
case CIDOID:
/* snprintf format strings to use for 64-bit integers */
#define INT64_FORMAT "%" PRId64
#define UINT64_FORMAT "%" PRIu64
+#define OID8_FORMAT "%" PRIu64
/*
* 128-bit signed and unsigned integers
#define FLOAT8PASSBYVAL true
/*
- * Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId,
+ * Oid, Oid8, RegProcedure, TransactionId, SubTransactionId, MultiXactId,
* CommandId
*/
#define FirstCommandId ((CommandId) 0)
#define InvalidCommandId (~(CommandId)0)
+/* 8-byte Object ID */
+typedef uint64 Oid8;
+
+#define InvalidOid8 ((Oid8) 0)
+#define OID8_MAX UINT64_MAX
/* ----------------
* Variable-length datatypes all share the 'struct varlena' header.
#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid))
+#define Oid8IsValid(objectId) ((bool) ((objectId) != InvalidOid8))
+
#define RegProcedureIsValid(p) OidIsValid(p)
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202601041
+#define CATALOG_VERSION_NO 202601071
#endif
{ aggfnoid => 'max(oid)', aggtransfn => 'oidlarger',
aggcombinefn => 'oidlarger', aggsortop => '>(oid,oid)',
aggtranstype => 'oid' },
+{ aggfnoid => 'max(oid8)', aggtransfn => 'oid8larger',
+ aggcombinefn => 'oid8larger', aggsortop => '>(oid8,oid8)',
+ aggtranstype => 'oid8' },
{ aggfnoid => 'max(float4)', aggtransfn => 'float4larger',
aggcombinefn => 'float4larger', aggsortop => '>(float4,float4)',
aggtranstype => 'float4' },
{ aggfnoid => 'min(oid)', aggtransfn => 'oidsmaller',
aggcombinefn => 'oidsmaller', aggsortop => '<(oid,oid)',
aggtranstype => 'oid' },
+{ aggfnoid => 'min(oid8)', aggtransfn => 'oid8smaller',
+ aggcombinefn => 'oid8smaller', aggsortop => '<(oid8,oid8)',
+ aggtranstype => 'oid8' },
{ aggfnoid => 'min(float4)', aggtransfn => 'float4smaller',
aggcombinefn => 'float4smaller', aggsortop => '<(float4,float4)',
aggtranstype => 'float4' },
{ amopfamily => 'btree/oid_ops', amoplefttype => 'oid', amoprighttype => 'oid',
amopstrategy => '5', amopopr => '>(oid,oid)', amopmethod => 'btree' },
+# btree oid8_ops
+
+{ amopfamily => 'btree/oid8_ops', amoplefttype => 'oid8',
+ amoprighttype => 'oid8', amopstrategy => '1', amopopr => '<(oid8,oid8)',
+ amopmethod => 'btree' },
+{ amopfamily => 'btree/oid8_ops', amoplefttype => 'oid8',
+ amoprighttype => 'oid8', amopstrategy => '2', amopopr => '<=(oid8,oid8)',
+ amopmethod => 'btree' },
+{ amopfamily => 'btree/oid8_ops', amoplefttype => 'oid8',
+ amoprighttype => 'oid8', amopstrategy => '3', amopopr => '=(oid8,oid8)',
+ amopmethod => 'btree' },
+{ amopfamily => 'btree/oid8_ops', amoplefttype => 'oid8',
+ amoprighttype => 'oid8', amopstrategy => '4', amopopr => '>=(oid8,oid8)',
+ amopmethod => 'btree' },
+{ amopfamily => 'btree/oid8_ops', amoplefttype => 'oid8',
+ amoprighttype => 'oid8', amopstrategy => '5', amopopr => '>(oid8,oid8)',
+ amopmethod => 'btree' },
+
# btree xid8_ops
{ amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8',
{ amopfamily => 'hash/oid_ops', amoplefttype => 'oid', amoprighttype => 'oid',
amopstrategy => '1', amopopr => '=(oid,oid)', amopmethod => 'hash' },
+# oid8_ops
+{ amopfamily => 'hash/oid8_ops', amoplefttype => 'oid8',
+ amoprighttype => 'oid8', amopstrategy => '1', amopopr => '=(oid8,oid8)',
+ amopmethod => 'hash' },
+
# oidvector_ops
{ amopfamily => 'hash/oidvector_ops', amoplefttype => 'oidvector',
amoprighttype => 'oidvector', amopstrategy => '1',
amprocrighttype => 'oid', amprocnum => '4', amproc => 'btequalimage' },
{ amprocfamily => 'btree/oid_ops', amproclefttype => 'oid',
amprocrighttype => 'oid', amprocnum => '6', amproc => 'btoidskipsupport' },
+{ amprocfamily => 'btree/oid8_ops', amproclefttype => 'oid8',
+ amprocrighttype => 'oid8', amprocnum => '1', amproc => 'btoid8cmp' },
+{ amprocfamily => 'btree/oid8_ops', amproclefttype => 'oid8',
+ amprocrighttype => 'oid8', amprocnum => '2', amproc => 'btoid8sortsupport' },
+{ amprocfamily => 'btree/oid8_ops', amproclefttype => 'oid8',
+ amprocrighttype => 'oid8', amprocnum => '4', amproc => 'btequalimage' },
+{ amprocfamily => 'btree/oid8_ops', amproclefttype => 'oid8',
+ amprocrighttype => 'oid8', amprocnum => '6', amproc => 'btoid8skipsupport' },
{ amprocfamily => 'btree/oidvector_ops', amproclefttype => 'oidvector',
amprocrighttype => 'oidvector', amprocnum => '1',
amproc => 'btoidvectorcmp' },
amprocrighttype => 'xid8', amprocnum => '1', amproc => 'hashxid8' },
{ amprocfamily => 'hash/xid8_ops', amproclefttype => 'xid8',
amprocrighttype => 'xid8', amprocnum => '2', amproc => 'hashxid8extended' },
+{ amprocfamily => 'hash/oid8_ops', amproclefttype => 'oid8',
+ amprocrighttype => 'oid8', amprocnum => '1', amproc => 'hashoid8' },
+{ amprocfamily => 'hash/oid8_ops', amproclefttype => 'oid8',
+ amprocrighttype => 'oid8', amprocnum => '2', amproc => 'hashoid8extended' },
{ amprocfamily => 'hash/cid_ops', amproclefttype => 'cid',
amprocrighttype => 'cid', amprocnum => '1', amproc => 'hashcid' },
{ amprocfamily => 'hash/cid_ops', amproclefttype => 'cid',
{ castsource => 'regdatabase', casttarget => 'int4', castfunc => '0',
castcontext => 'a', castmethod => 'b' },
+# OID8 category: allow implicit conversion from any integral type (including
+# int8), as well as assignment coercion to int8.
+{ castsource => 'int8', casttarget => 'oid8', castfunc => '0',
+ castcontext => 'i', castmethod => 'b' },
+{ castsource => 'int2', casttarget => 'oid8', castfunc => 'int8(int2)',
+ castcontext => 'i', castmethod => 'f' },
+{ castsource => 'int4', casttarget => 'oid8', castfunc => 'int8(int4)',
+ castcontext => 'i', castmethod => 'f' },
+{ castsource => 'oid8', casttarget => 'int8', castfunc => '0',
+ castcontext => 'a', castmethod => 'b' },
+# Assignment coercion from oid to oid8.
+{ castsource => 'oid', casttarget => 'oid8', castfunc => 'oid8(oid)',
+ castcontext => 'a', castmethod => 'f' },
+
# String category
{ castsource => 'text', casttarget => 'bpchar', castfunc => '0',
castcontext => 'i', castmethod => 'b' },
opcintype => 'xid8' },
{ opcmethod => 'btree', opcname => 'xid8_ops', opcfamily => 'btree/xid8_ops',
opcintype => 'xid8' },
+{ opcmethod => 'hash', opcname => 'oid8_ops', opcfamily => 'hash/oid8_ops',
+ opcintype => 'oid8' },
+{ opcmethod => 'btree', opcname => 'oid8_ops', opcfamily => 'btree/oid8_ops',
+ opcintype => 'oid8' },
{ opcmethod => 'hash', opcname => 'cid_ops', opcfamily => 'hash/cid_ops',
opcintype => 'cid' },
{ opcmethod => 'hash', opcname => 'tid_ops', opcfamily => 'hash/tid_ops',
oprcode => 'multirange_after_multirange', oprrest => 'multirangesel',
oprjoin => 'scalargtjoinsel' },
+{ oid => '8262', descr => 'equal',
+ oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'oid8',
+ oprright => 'oid8', oprresult => 'bool', oprcom => '=(oid8,oid8)',
+ oprnegate => '<>(oid8,oid8)', oprcode => 'oid8eq', oprrest => 'eqsel',
+ oprjoin => 'eqjoinsel' },
+{ oid => '8263', descr => 'not equal',
+ oprname => '<>', oprleft => 'oid8', oprright => 'oid8', oprresult => 'bool',
+ oprcom => '<>(oid8,oid8)', oprnegate => '=(oid8,oid8)', oprcode => 'oid8ne',
+ oprrest => 'neqsel', oprjoin => 'neqjoinsel' },
+{ oid => '8264', descr => 'less than',
+ oprname => '<', oprleft => 'oid8', oprright => 'oid8', oprresult => 'bool',
+ oprcom => '>(oid8,oid8)', oprnegate => '>=(oid8,oid8)', oprcode => 'oid8lt',
+ oprrest => 'scalarltsel', oprjoin => 'scalarltjoinsel' },
+{ oid => '8265', descr => 'greater than',
+ oprname => '>', oprleft => 'oid8', oprright => 'oid8', oprresult => 'bool',
+ oprcom => '<(oid8,oid8)', oprnegate => '<=(oid8,oid8)', oprcode => 'oid8gt',
+ oprrest => 'scalargtsel', oprjoin => 'scalargtjoinsel' },
+{ oid => '8266', descr => 'less than or equal',
+ oprname => '<=', oprleft => 'oid8', oprright => 'oid8', oprresult => 'bool',
+ oprcom => '>=(oid8,oid8)', oprnegate => '>(oid8,oid8)', oprcode => 'oid8le',
+ oprrest => 'scalarlesel', oprjoin => 'scalarlejoinsel' },
+{ oid => '8267', descr => 'greater than or equal',
+ oprname => '>=', oprleft => 'oid8', oprright => 'oid8', oprresult => 'bool',
+ oprcom => '<=(oid8,oid8)', oprnegate => '<(oid8,oid8)', oprcode => 'oid8ge',
+ oprrest => 'scalargesel', oprjoin => 'scalargejoinsel' },
+
]
opfmethod => 'hash', opfname => 'xid8_ops' },
{ oid => '5067',
opfmethod => 'btree', opfname => 'xid8_ops' },
+{ oid => '8278',
+ opfmethod => 'hash', opfname => 'oid8_ops' },
+{ oid => '8279',
+ opfmethod => 'btree', opfname => 'oid8_ops' },
{ oid => '2226',
opfmethod => 'hash', opfname => 'cid_ops' },
{ oid => '2227',
{ oid => '6405', descr => 'skip support',
proname => 'btoidskipsupport', prorettype => 'void',
proargtypes => 'internal', prosrc => 'btoidskipsupport' },
+{ oid => '8282', descr => 'less-equal-greater',
+ proname => 'btoid8cmp', proleakproof => 't', prorettype => 'int4',
+ proargtypes => 'oid8 oid8', prosrc => 'btoid8cmp' },
+{ oid => '8283', descr => 'sort support',
+ proname => 'btoid8sortsupport', prorettype => 'void',
+ proargtypes => 'internal', prosrc => 'btoid8sortsupport' },
+{ oid => '8284', descr => 'skip support',
+ proname => 'btoid8skipsupport', prorettype => 'void',
+ proargtypes => 'internal', prosrc => 'btoid8skipsupport' },
{ oid => '404', descr => 'less-equal-greater',
proname => 'btoidvectorcmp', proleakproof => 't', prorettype => 'int4',
proargtypes => 'oidvector oidvector', prosrc => 'btoidvectorcmp' },
proargnames => '{pid,io_id,io_generation,state,operation,off,length,target,handle_data_len,raw_result,result,target_desc,f_sync,f_localmem,f_buffered}',
prosrc => 'pg_get_aios' },
+# oid8 related functions
+{ oid => '8255', descr => 'convert oid to oid8',
+ proname => 'oid8', prorettype => 'oid8', proargtypes => 'oid',
+ prosrc => 'oidtooid8' },
+{ oid => '8257', descr => 'I/O',
+ proname => 'oid8in', prorettype => 'oid8', proargtypes => 'cstring',
+ prosrc => 'oid8in' },
+{ oid => '8258', descr => 'I/O',
+ proname => 'oid8out', prorettype => 'cstring', proargtypes => 'oid8',
+ prosrc => 'oid8out' },
+{ oid => '8259', descr => 'I/O',
+ proname => 'oid8recv', prorettype => 'oid8', proargtypes => 'internal',
+ prosrc => 'oid8recv' },
+{ oid => '8260', descr => 'I/O',
+ proname => 'oid8send', prorettype => 'bytea', proargtypes => 'oid8',
+ prosrc => 'oid8send' },
+# Comparators
+{ oid => '8268',
+ proname => 'oid8eq', proleakproof => 't', prorettype => 'bool',
+ proargtypes => 'oid8 oid8', prosrc => 'oid8eq' },
+{ oid => '8269',
+ proname => 'oid8ne', proleakproof => 't', prorettype => 'bool',
+ proargtypes => 'oid8 oid8', prosrc => 'oid8ne' },
+{ oid => '8270',
+ proname => 'oid8lt', proleakproof => 't', prorettype => 'bool',
+ proargtypes => 'oid8 oid8', prosrc => 'oid8lt' },
+{ oid => '8271',
+ proname => 'oid8le', proleakproof => 't', prorettype => 'bool',
+ proargtypes => 'oid8 oid8', prosrc => 'oid8le' },
+{ oid => '8272',
+ proname => 'oid8gt', proleakproof => 't', prorettype => 'bool',
+ proargtypes => 'oid8 oid8', prosrc => 'oid8gt' },
+{ oid => '8273',
+ proname => 'oid8ge', proleakproof => 't', prorettype => 'bool',
+ proargtypes => 'oid8 oid8', prosrc => 'oid8ge' },
+# Aggregates
+{ oid => '8274', descr => 'larger of two',
+ proname => 'oid8larger', prorettype => 'oid8', proargtypes => 'oid8 oid8',
+ prosrc => 'oid8larger' },
+{ oid => '8275', descr => 'smaller of two',
+ proname => 'oid8smaller', prorettype => 'oid8', proargtypes => 'oid8 oid8',
+ prosrc => 'oid8smaller' },
+{ oid => '8276', descr => 'maximum value of all oid8 input values',
+ proname => 'max', prokind => 'a', proisstrict => 'f', prorettype => 'oid8',
+ proargtypes => 'oid8', prosrc => 'aggregate_dummy' },
+{ oid => '8277', descr => 'minimum value of all oid8 input values',
+ proname => 'min', prokind => 'a', proisstrict => 'f', prorettype => 'oid8',
+ proargtypes => 'oid8', prosrc => 'aggregate_dummy' },
+{ oid => '8280', descr => 'hash',
+ proname => 'hashoid8', prorettype => 'int4', proargtypes => 'oid8',
+ prosrc => 'hashoid8' },
+{ oid => '8281', descr => 'hash',
+ proname => 'hashoid8extended', prorettype => 'int8',
+ proargtypes => 'oid8 int8', prosrc => 'hashoid8extended' },
+
]
typreceive => 'brin_minmax_multi_summary_recv',
typsend => 'brin_minmax_multi_summary_send', typalign => 'i',
typstorage => 'x', typcollation => 'default' },
+{ oid => '8256', array_type_oid => '8261',
+ descr => 'object identifier(oid8), 8 bytes',
+ typname => 'oid8', typlen => '8', typbyval => 't', typcategory => 'N',
+ typinput => 'oid8in', typoutput => 'oid8out', typreceive => 'oid8recv',
+ typsend => 'oid8send', typalign => 'd' },
]
#define PG_GETARG_CHAR(n) DatumGetChar(PG_GETARG_DATUM(n))
#define PG_GETARG_BOOL(n) DatumGetBool(PG_GETARG_DATUM(n))
#define PG_GETARG_OID(n) DatumGetObjectId(PG_GETARG_DATUM(n))
+#define PG_GETARG_OID8(n) DatumGetObjectId8(PG_GETARG_DATUM(n))
#define PG_GETARG_POINTER(n) DatumGetPointer(PG_GETARG_DATUM(n))
#define PG_GETARG_CSTRING(n) DatumGetCString(PG_GETARG_DATUM(n))
#define PG_GETARG_NAME(n) DatumGetName(PG_GETARG_DATUM(n))
#define PG_RETURN_CHAR(x) return CharGetDatum(x)
#define PG_RETURN_BOOL(x) return BoolGetDatum(x)
#define PG_RETURN_OID(x) return ObjectIdGetDatum(x)
+#define PG_RETURN_OID8(x) return ObjectId8GetDatum(x)
#define PG_RETURN_POINTER(x) return PointerGetDatum(x)
#define PG_RETURN_CSTRING(x) return CStringGetDatum(x)
#define PG_RETURN_NAME(x) return NameGetDatum(x)
return (Datum) X;
}
+/*
+ * DatumGetObjectId8
+ * Returns 8-byte object identifier value of a datum.
+ */
+static inline Oid8
+DatumGetObjectId8(Datum X)
+{
+ return (Oid8) X;
+}
+
+/*
+ * ObjectId8GetDatum
+ * Returns datum representation for an 8-byte object identifier
+ */
+static inline Datum
+ObjectId8GetDatum(Oid8 X)
+{
+ return (Datum) X;
+}
+
/*
* DatumGetTransactionId
* Returns transaction identifier value of a datum.
-------+----------+-----------+-----------
(0 rows)
+SELECT v as value, hashoid8(v)::bit(32) as standard,
+ hashoid8extended(v, 0)::bit(32) as extended0,
+ hashoid8extended(v, 1)::bit(32) as extended1
+FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v)
+WHERE hashoid8(v)::bit(32) != hashoid8extended(v, 0)::bit(32)
+ OR hashoid8(v)::bit(32) = hashoid8extended(v, 1)::bit(32);
+ value | standard | extended0 | extended1
+-------+----------+-----------+-----------
+(0 rows)
+
SELECT v as value, hashchar(v)::bit(32) as standard,
hashcharextended(v, 0)::bit(32) as extended0,
hashcharextended(v, 1)::bit(32) as extended1
--- /dev/null
+--
+-- OID8
+--
+CREATE TABLE OID8_TBL(f1 oid8);
+INSERT INTO OID8_TBL(f1) VALUES ('1234');
+INSERT INTO OID8_TBL(f1) VALUES ('1235');
+INSERT INTO OID8_TBL(f1) VALUES ('987');
+INSERT INTO OID8_TBL(f1) VALUES ('-1040');
+INSERT INTO OID8_TBL(f1) VALUES ('99999999');
+INSERT INTO OID8_TBL(f1) VALUES ('5 ');
+INSERT INTO OID8_TBL(f1) VALUES (' 10 ');
+INSERT INTO OID8_TBL(f1) VALUES ('123456789012345678');
+-- UINT64_MAX
+INSERT INTO OID8_TBL(f1) VALUES ('18446744073709551615');
+-- leading/trailing hard tab is also allowed
+INSERT INTO OID8_TBL(f1) VALUES (' 15 ');
+-- bad inputs
+INSERT INTO OID8_TBL(f1) VALUES ('');
+ERROR: invalid input syntax for type oid8: ""
+LINE 1: INSERT INTO OID8_TBL(f1) VALUES ('');
+ ^
+INSERT INTO OID8_TBL(f1) VALUES (' ');
+ERROR: invalid input syntax for type oid8: " "
+LINE 1: INSERT INTO OID8_TBL(f1) VALUES (' ');
+ ^
+INSERT INTO OID8_TBL(f1) VALUES ('asdfasd');
+ERROR: invalid input syntax for type oid8: "asdfasd"
+LINE 1: INSERT INTO OID8_TBL(f1) VALUES ('asdfasd');
+ ^
+INSERT INTO OID8_TBL(f1) VALUES ('99asdfasd');
+ERROR: invalid input syntax for type oid8: "99asdfasd"
+LINE 1: INSERT INTO OID8_TBL(f1) VALUES ('99asdfasd');
+ ^
+INSERT INTO OID8_TBL(f1) VALUES ('5 d');
+ERROR: invalid input syntax for type oid8: "5 d"
+LINE 1: INSERT INTO OID8_TBL(f1) VALUES ('5 d');
+ ^
+INSERT INTO OID8_TBL(f1) VALUES (' 5d');
+ERROR: invalid input syntax for type oid8: " 5d"
+LINE 1: INSERT INTO OID8_TBL(f1) VALUES (' 5d');
+ ^
+INSERT INTO OID8_TBL(f1) VALUES ('5 5');
+ERROR: invalid input syntax for type oid8: "5 5"
+LINE 1: INSERT INTO OID8_TBL(f1) VALUES ('5 5');
+ ^
+INSERT INTO OID8_TBL(f1) VALUES (' - 500');
+ERROR: invalid input syntax for type oid8: " - 500"
+LINE 1: INSERT INTO OID8_TBL(f1) VALUES (' - 500');
+ ^
+INSERT INTO OID8_TBL(f1) VALUES ('3908203590239580293850293850329485');
+ERROR: value "3908203590239580293850293850329485" is out of range for type oid8
+LINE 1: INSERT INTO OID8_TBL(f1) VALUES ('39082035902395802938502938...
+ ^
+INSERT INTO OID8_TBL(f1) VALUES ('-1204982019841029840928340329840934');
+ERROR: value "-1204982019841029840928340329840934" is out of range for type oid8
+LINE 1: INSERT INTO OID8_TBL(f1) VALUES ('-1204982019841029840928340...
+ ^
+-- UINT64_MAX + 1
+INSERT INTO OID8_TBL(f1) VALUES ('18446744073709551616');
+ERROR: value "18446744073709551616" is out of range for type oid8
+LINE 1: INSERT INTO OID8_TBL(f1) VALUES ('18446744073709551616');
+ ^
+SELECT * FROM OID8_TBL;
+ f1
+----------------------
+ 1234
+ 1235
+ 987
+ 18446744073709550576
+ 99999999
+ 5
+ 10
+ 123456789012345678
+ 18446744073709551615
+ 15
+(10 rows)
+
+-- Also try it with non-error-throwing API
+SELECT pg_input_is_valid('1234', 'oid8');
+ pg_input_is_valid
+-------------------
+ t
+(1 row)
+
+SELECT pg_input_is_valid('01XYZ', 'oid8');
+ pg_input_is_valid
+-------------------
+ f
+(1 row)
+
+SELECT * FROM pg_input_error_info('01XYZ', 'oid8');
+ message | detail | hint | sql_error_code
+---------------------------------------------+--------+------+----------------
+ invalid input syntax for type oid8: "01XYZ" | | | 22P02
+(1 row)
+
+SELECT pg_input_is_valid('3908203590239580293850293850329485', 'oid8');
+ pg_input_is_valid
+-------------------
+ f
+(1 row)
+
+SELECT * FROM pg_input_error_info('-1204982019841029840928340329840934', 'oid8');
+ message | detail | hint | sql_error_code
+---------------------------------------------------------------------------+--------+------+----------------
+ value "-1204982019841029840928340329840934" is out of range for type oid8 | | | 22003
+(1 row)
+
+-- Operators
+SELECT o.* FROM OID8_TBL o WHERE o.f1 = 1234;
+ f1
+------
+ 1234
+(1 row)
+
+SELECT o.* FROM OID8_TBL o WHERE o.f1 <> '1234';
+ f1
+----------------------
+ 1235
+ 987
+ 18446744073709550576
+ 99999999
+ 5
+ 10
+ 123456789012345678
+ 18446744073709551615
+ 15
+(9 rows)
+
+SELECT o.* FROM OID8_TBL o WHERE o.f1 <= '1234';
+ f1
+------
+ 1234
+ 987
+ 5
+ 10
+ 15
+(5 rows)
+
+SELECT o.* FROM OID8_TBL o WHERE o.f1 < '1234';
+ f1
+-----
+ 987
+ 5
+ 10
+ 15
+(4 rows)
+
+SELECT o.* FROM OID8_TBL o WHERE o.f1 >= '1234';
+ f1
+----------------------
+ 1234
+ 1235
+ 18446744073709550576
+ 99999999
+ 123456789012345678
+ 18446744073709551615
+(6 rows)
+
+SELECT o.* FROM OID8_TBL o WHERE o.f1 > '1234';
+ f1
+----------------------
+ 1235
+ 18446744073709550576
+ 99999999
+ 123456789012345678
+ 18446744073709551615
+(5 rows)
+
+-- Casts
+SELECT 1::int2::oid8;
+ oid8
+------
+ 1
+(1 row)
+
+SELECT 1::int4::oid8;
+ oid8
+------
+ 1
+(1 row)
+
+SELECT 1::int8::oid8;
+ oid8
+------
+ 1
+(1 row)
+
+SELECT 1::oid8::int8;
+ int8
+------
+ 1
+(1 row)
+
+SELECT 1::oid::oid8; -- ok
+ oid8
+------
+ 1
+(1 row)
+
+SELECT 1::oid8::oid; -- not ok
+ERROR: cannot cast type oid8 to oid
+LINE 1: SELECT 1::oid8::oid;
+ ^
+-- Aggregates
+SELECT min(f1), max(f1) FROM OID8_TBL;
+ min | max
+-----+----------------------
+ 5 | 18446744073709551615
+(1 row)
+
+-- Check btree and hash opclasses
+EXPLAIN (COSTS OFF)
+SELECT DISTINCT (i || '000000000000' || j)::oid8 f
+ FROM generate_series(1, 10) i,
+ generate_series(1, 10) j,
+ generate_series(1, 5) k
+ WHERE i <= 10 AND j > 0 AND j <= 10
+ ORDER BY f;
+ QUERY PLAN
+-----------------------------------------------------------------------------------
+ Sort
+ Sort Key: (((((i.i)::text || '000000000000'::text) || (j.j)::text))::oid8)
+ -> HashAggregate
+ Group Key: ((((i.i)::text || '000000000000'::text) || (j.j)::text))::oid8
+ -> Nested Loop
+ -> Function Scan on generate_series k
+ -> Materialize
+ -> Nested Loop
+ -> Function Scan on generate_series j
+ Filter: ((j > 0) AND (j <= 10))
+ -> Function Scan on generate_series i
+ Filter: (i <= 10)
+(12 rows)
+
+SELECT DISTINCT (i || '000000000000' || j)::oid8 f
+ FROM generate_series(1, 10) i,
+ generate_series(1, 10) j,
+ generate_series(1, 5) k
+ WHERE i <= 10 AND j > 0 AND j <= 10
+ ORDER BY f;
+ f
+------------------
+ 10000000000001
+ 10000000000002
+ 10000000000003
+ 10000000000004
+ 10000000000005
+ 10000000000006
+ 10000000000007
+ 10000000000008
+ 10000000000009
+ 20000000000001
+ 20000000000002
+ 20000000000003
+ 20000000000004
+ 20000000000005
+ 20000000000006
+ 20000000000007
+ 20000000000008
+ 20000000000009
+ 30000000000001
+ 30000000000002
+ 30000000000003
+ 30000000000004
+ 30000000000005
+ 30000000000006
+ 30000000000007
+ 30000000000008
+ 30000000000009
+ 40000000000001
+ 40000000000002
+ 40000000000003
+ 40000000000004
+ 40000000000005
+ 40000000000006
+ 40000000000007
+ 40000000000008
+ 40000000000009
+ 50000000000001
+ 50000000000002
+ 50000000000003
+ 50000000000004
+ 50000000000005
+ 50000000000006
+ 50000000000007
+ 50000000000008
+ 50000000000009
+ 60000000000001
+ 60000000000002
+ 60000000000003
+ 60000000000004
+ 60000000000005
+ 60000000000006
+ 60000000000007
+ 60000000000008
+ 60000000000009
+ 70000000000001
+ 70000000000002
+ 70000000000003
+ 70000000000004
+ 70000000000005
+ 70000000000006
+ 70000000000007
+ 70000000000008
+ 70000000000009
+ 80000000000001
+ 80000000000002
+ 80000000000003
+ 80000000000004
+ 80000000000005
+ 80000000000006
+ 80000000000007
+ 80000000000008
+ 80000000000009
+ 90000000000001
+ 90000000000002
+ 90000000000003
+ 90000000000004
+ 90000000000005
+ 90000000000006
+ 90000000000007
+ 90000000000008
+ 90000000000009
+ 100000000000001
+ 100000000000002
+ 100000000000003
+ 100000000000004
+ 100000000000005
+ 100000000000006
+ 100000000000007
+ 100000000000008
+ 100000000000009
+ 100000000000010
+ 200000000000010
+ 300000000000010
+ 400000000000010
+ 500000000000010
+ 600000000000010
+ 700000000000010
+ 800000000000010
+ 900000000000010
+ 1000000000000010
+(100 rows)
+
+-- 3-way compare for btrees
+SELECT btoid8cmp(1::oid8, 2::oid8);
+ btoid8cmp
+-----------
+ -1
+(1 row)
+
+SELECT btoid8cmp(2::oid8, 2::oid8);
+ btoid8cmp
+-----------
+ 0
+(1 row)
+
+SELECT btoid8cmp(2::oid8, 1::oid8);
+ btoid8cmp
+-----------
+ 1
+(1 row)
+
+-- oid8 has btree and hash opclasses
+CREATE INDEX on OID8_TBL USING btree(f1);
+CREATE INDEX ON OID8_TBL USING hash(f1);
+DROP TABLE OID8_TBL;
bytea(bigint)
bytea_larger(bytea,bytea)
bytea_smaller(bytea,bytea)
+oid8eq(oid8,oid8)
+oid8ne(oid8,oid8)
+oid8lt(oid8,oid8)
+oid8le(oid8,oid8)
+oid8gt(oid8,oid8)
+oid8ge(oid8,oid8)
+btoid8cmp(oid8,oid8)
-- Check that functions without argument are not marked as leakproof.
SELECT p1.oid::regprocedure
FROM pg_proc p1 JOIN pg_namespace pn
'abc'::refcursor,
'1 2'::int2vector,
'1 2'::oidvector,
+ '1234'::oid8,
format('%I=UC/%I', USER, USER)::aclitem AS aclitem,
'a fat cat sat on a mat and ate a fat rat'::tsvector,
'fat & rat'::tsquery,
# geometry depends on point, lseg, line, box, path, polygon, circle
# horology depends on date, time, timetz, timestamp, timestamptz, interval
# ----------
-test: geometry horology tstypes regex type_sanity opr_sanity misc_sanity comments expressions unicode xid mvcc database stats_import pg_ndistinct pg_dependencies
+test: geometry horology tstypes regex type_sanity opr_sanity misc_sanity comments expressions unicode xid mvcc database stats_import pg_ndistinct pg_dependencies oid8
# ----------
# Load huge amounts of data
WHERE hashoid(v)::bit(32) != hashoidextended(v, 0)::bit(32)
OR hashoid(v)::bit(32) = hashoidextended(v, 1)::bit(32);
+SELECT v as value, hashoid8(v)::bit(32) as standard,
+ hashoid8extended(v, 0)::bit(32) as extended0,
+ hashoid8extended(v, 1)::bit(32) as extended1
+FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v)
+WHERE hashoid8(v)::bit(32) != hashoid8extended(v, 0)::bit(32)
+ OR hashoid8(v)::bit(32) = hashoid8extended(v, 1)::bit(32);
+
SELECT v as value, hashchar(v)::bit(32) as standard,
hashcharextended(v, 0)::bit(32) as extended0,
hashcharextended(v, 1)::bit(32) as extended1
--- /dev/null
+--
+-- OID8
+--
+
+CREATE TABLE OID8_TBL(f1 oid8);
+
+INSERT INTO OID8_TBL(f1) VALUES ('1234');
+INSERT INTO OID8_TBL(f1) VALUES ('1235');
+INSERT INTO OID8_TBL(f1) VALUES ('987');
+INSERT INTO OID8_TBL(f1) VALUES ('-1040');
+INSERT INTO OID8_TBL(f1) VALUES ('99999999');
+INSERT INTO OID8_TBL(f1) VALUES ('5 ');
+INSERT INTO OID8_TBL(f1) VALUES (' 10 ');
+INSERT INTO OID8_TBL(f1) VALUES ('123456789012345678');
+-- UINT64_MAX
+INSERT INTO OID8_TBL(f1) VALUES ('18446744073709551615');
+-- leading/trailing hard tab is also allowed
+INSERT INTO OID8_TBL(f1) VALUES (' 15 ');
+
+-- bad inputs
+INSERT INTO OID8_TBL(f1) VALUES ('');
+INSERT INTO OID8_TBL(f1) VALUES (' ');
+INSERT INTO OID8_TBL(f1) VALUES ('asdfasd');
+INSERT INTO OID8_TBL(f1) VALUES ('99asdfasd');
+INSERT INTO OID8_TBL(f1) VALUES ('5 d');
+INSERT INTO OID8_TBL(f1) VALUES (' 5d');
+INSERT INTO OID8_TBL(f1) VALUES ('5 5');
+INSERT INTO OID8_TBL(f1) VALUES (' - 500');
+INSERT INTO OID8_TBL(f1) VALUES ('3908203590239580293850293850329485');
+INSERT INTO OID8_TBL(f1) VALUES ('-1204982019841029840928340329840934');
+-- UINT64_MAX + 1
+INSERT INTO OID8_TBL(f1) VALUES ('18446744073709551616');
+
+SELECT * FROM OID8_TBL;
+
+-- Also try it with non-error-throwing API
+SELECT pg_input_is_valid('1234', 'oid8');
+SELECT pg_input_is_valid('01XYZ', 'oid8');
+SELECT * FROM pg_input_error_info('01XYZ', 'oid8');
+SELECT pg_input_is_valid('3908203590239580293850293850329485', 'oid8');
+SELECT * FROM pg_input_error_info('-1204982019841029840928340329840934', 'oid8');
+
+-- Operators
+SELECT o.* FROM OID8_TBL o WHERE o.f1 = 1234;
+SELECT o.* FROM OID8_TBL o WHERE o.f1 <> '1234';
+SELECT o.* FROM OID8_TBL o WHERE o.f1 <= '1234';
+SELECT o.* FROM OID8_TBL o WHERE o.f1 < '1234';
+SELECT o.* FROM OID8_TBL o WHERE o.f1 >= '1234';
+SELECT o.* FROM OID8_TBL o WHERE o.f1 > '1234';
+
+-- Casts
+SELECT 1::int2::oid8;
+SELECT 1::int4::oid8;
+SELECT 1::int8::oid8;
+SELECT 1::oid8::int8;
+SELECT 1::oid::oid8; -- ok
+SELECT 1::oid8::oid; -- not ok
+
+-- Aggregates
+SELECT min(f1), max(f1) FROM OID8_TBL;
+
+-- Check btree and hash opclasses
+EXPLAIN (COSTS OFF)
+SELECT DISTINCT (i || '000000000000' || j)::oid8 f
+ FROM generate_series(1, 10) i,
+ generate_series(1, 10) j,
+ generate_series(1, 5) k
+ WHERE i <= 10 AND j > 0 AND j <= 10
+ ORDER BY f;
+
+SELECT DISTINCT (i || '000000000000' || j)::oid8 f
+ FROM generate_series(1, 10) i,
+ generate_series(1, 10) j,
+ generate_series(1, 5) k
+ WHERE i <= 10 AND j > 0 AND j <= 10
+ ORDER BY f;
+
+-- 3-way compare for btrees
+SELECT btoid8cmp(1::oid8, 2::oid8);
+SELECT btoid8cmp(2::oid8, 2::oid8);
+SELECT btoid8cmp(2::oid8, 1::oid8);
+
+-- oid8 has btree and hash opclasses
+CREATE INDEX on OID8_TBL USING btree(f1);
+CREATE INDEX ON OID8_TBL USING hash(f1);
+
+DROP TABLE OID8_TBL;
'abc'::refcursor,
'1 2'::int2vector,
'1 2'::oidvector,
+ '1234'::oid8,
format('%I=UC/%I', USER, USER)::aclitem AS aclitem,
'a fat cat sat on a mat and ate a fat rat'::tsvector,
'fat & rat'::tsquery,