1
0
mirror of https://github.com/postgres/postgres.git synced 2026-01-26 09:41:40 +03:00

Add data type oid8, 64-bit unsigned identifier

This new identifier type provides support for 64-bit unsigned values,
to be used in catalogs, like OIDs.  An advantage of a new data type is
that it becomes easier to grep for it in the code when assigning this
type to a catalog attribute, linking it to dedicated APIs and internal
structures.

The following operators are added in this commit, with dedicated tests:
- Casts with integer types and OID.
- btree and hash operators
- min/max functions.
- C type with related macros and defines, named around "Oid8".

This has been mentioned as useful on its own on the thread to add
support for 64-bit TOAST values, so as it becomes possible to attach
this data type to the TOAST code and catalog definitions.  However, as
this concept can apply to many more areas, it is implemented as its own
independent change.  This is based on a discussion with Andres Freund
and Tom Lane.

Bump catalog version.

Author: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Greg Burd <greg@burd.me>
Reviewed-by: Nikhil Kumar Veldanda <veldanda.nikhilkumar17@gmail.com>
Discussion: https://postgr.es/m/1891064.1754681536@sss.pgh.pa.us
This commit is contained in:
Michael Paquier
2026-01-07 11:37:00 +09:00
parent af2d4ca191
commit b139bd3b6e
30 changed files with 953 additions and 9 deletions

View File

@@ -4724,6 +4724,10 @@ INSERT INTO mytable VALUES(-1); -- fails
<primary>oid</primary> <primary>oid</primary>
</indexterm> </indexterm>
<indexterm zone="datatype-oid">
<primary>oid8</primary>
</indexterm>
<indexterm zone="datatype-oid"> <indexterm zone="datatype-oid">
<primary>regclass</primary> <primary>regclass</primary>
</indexterm> </indexterm>
@@ -4807,8 +4811,16 @@ INSERT INTO mytable VALUES(-1); -- fails
</para> </para>
<para> <para>
The <type>oid</type> type itself has few operations beyond comparison. In some contexts, a 64-bit variant <type>oid8</type> can be used.
It can be cast to integer, however, and then manipulated using the 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 standard integer operators. (Beware of possible
signed-versus-unsigned confusion if you do this.) signed-versus-unsigned confusion if you do this.)
</para> </para>

View File

@@ -508,8 +508,8 @@
Computes the maximum of the non-null input Computes the maximum of the non-null input
values. Available for any numeric, string, date/time, or enum type, values. Available for any numeric, string, date/time, or enum type,
as well as <type>bytea</type>, <type>inet</type>, <type>interval</type>, as well as <type>bytea</type>, <type>inet</type>, <type>interval</type>,
<type>money</type>, <type>oid</type>, <type>pg_lsn</type>, <type>money</type>, <type>oid</type>, <type>oid8</type>,
<type>tid</type>, <type>xid8</type>, <type>pg_lsn</type>, <type>tid</type>, <type>xid8</type>,
and also arrays and composite types containing sortable data types. and also arrays and composite types containing sortable data types.
</para></entry> </para></entry>
<entry>Yes</entry> <entry>Yes</entry>
@@ -527,8 +527,8 @@
Computes the minimum of the non-null input Computes the minimum of the non-null input
values. Available for any numeric, string, date/time, or enum type, values. Available for any numeric, string, date/time, or enum type,
as well as <type>bytea</type>, <type>inet</type>, <type>interval</type>, as well as <type>bytea</type>, <type>inet</type>, <type>interval</type>,
<type>money</type>, <type>oid</type>, <type>pg_lsn</type>, <type>money</type>, <type>oid</type>, <type>oid8</type>,
<type>tid</type>, <type>xid8</type>, <type>pg_lsn</type>, <type>tid</type>, <type>xid8</type>,
and also arrays and composite types containing sortable data types. and also arrays and composite types containing sortable data types.
</para></entry> </para></entry>
<entry>Yes</entry> <entry>Yes</entry>

View File

@@ -498,6 +498,88 @@ btoidskipsupport(PG_FUNCTION_ARGS)
PG_RETURN_VOID(); 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 Datum
btoidvectorcmp(PG_FUNCTION_ARGS) btoidvectorcmp(PG_FUNCTION_ARGS)
{ {

View File

@@ -115,6 +115,8 @@ static const struct typinfo TypInfo[] = {
F_TEXTIN, F_TEXTOUT}, F_TEXTIN, F_TEXTOUT},
{"oid", OIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid, {"oid", OIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
F_OIDIN, F_OIDOUT}, 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, {"tid", TIDOID, 0, 6, false, TYPALIGN_SHORT, TYPSTORAGE_PLAIN, InvalidOid,
F_TIDIN, F_TIDOUT}, F_TIDIN, F_TIDOUT},
{"xid", XIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid, {"xid", XIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,

View File

@@ -77,6 +77,7 @@ OBJS = \
numeric.o \ numeric.o \
numutils.o \ numutils.o \
oid.o \ oid.o \
oid8.o \
oracle_compat.o \ oracle_compat.o \
orderedsetaggs.o \ orderedsetaggs.o \
partitionfuncs.o \ partitionfuncs.o \

View File

@@ -1370,6 +1370,14 @@ oidtoi8(PG_FUNCTION_ARGS)
PG_RETURN_INT64((int64) arg); 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 * non-persistent numeric series generator
*/ */

View File

@@ -73,6 +73,7 @@ backend_sources += files(
'network_spgist.c', 'network_spgist.c',
'numutils.c', 'numutils.c',
'oid.c', 'oid.c',
'oid8.c',
'oracle_compat.c', 'oracle_compat.c',
'orderedsetaggs.c', 'orderedsetaggs.c',
'partitionfuncs.c', 'partitionfuncs.c',

View File

@@ -0,0 +1,168 @@
/*-------------------------------------------------------------------------
*
* 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);
}

View File

@@ -3821,6 +3821,7 @@ column_type_alignment(Oid ftype)
case FLOAT8OID: case FLOAT8OID:
case NUMERICOID: case NUMERICOID:
case OIDOID: case OIDOID:
case OID8OID:
case XIDOID: case XIDOID:
case XID8OID: case XID8OID:
case CIDOID: case CIDOID:

View File

@@ -569,6 +569,7 @@ typedef uint32 bits32; /* >= 32 bits */
/* snprintf format strings to use for 64-bit integers */ /* snprintf format strings to use for 64-bit integers */
#define INT64_FORMAT "%" PRId64 #define INT64_FORMAT "%" PRId64
#define UINT64_FORMAT "%" PRIu64 #define UINT64_FORMAT "%" PRIu64
#define OID8_FORMAT "%" PRIu64
/* /*
* 128-bit signed and unsigned integers * 128-bit signed and unsigned integers
@@ -655,7 +656,7 @@ typedef double float8;
#define FLOAT8PASSBYVAL true #define FLOAT8PASSBYVAL true
/* /*
* Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId, * Oid, Oid8, RegProcedure, TransactionId, SubTransactionId, MultiXactId,
* CommandId * CommandId
*/ */
@@ -687,6 +688,11 @@ typedef uint32 CommandId;
#define FirstCommandId ((CommandId) 0) #define FirstCommandId ((CommandId) 0)
#define InvalidCommandId (~(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. * Variable-length datatypes all share the 'struct varlena' header.
@@ -787,6 +793,8 @@ typedef NameData *Name;
#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid)) #define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid))
#define Oid8IsValid(objectId) ((bool) ((objectId) != InvalidOid8))
#define RegProcedureIsValid(p) OidIsValid(p) #define RegProcedureIsValid(p) OidIsValid(p)

View File

@@ -57,6 +57,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202601041 #define CATALOG_VERSION_NO 202601071
#endif #endif

View File

@@ -104,6 +104,9 @@
{ aggfnoid => 'max(oid)', aggtransfn => 'oidlarger', { aggfnoid => 'max(oid)', aggtransfn => 'oidlarger',
aggcombinefn => 'oidlarger', aggsortop => '>(oid,oid)', aggcombinefn => 'oidlarger', aggsortop => '>(oid,oid)',
aggtranstype => 'oid' }, aggtranstype => 'oid' },
{ aggfnoid => 'max(oid8)', aggtransfn => 'oid8larger',
aggcombinefn => 'oid8larger', aggsortop => '>(oid8,oid8)',
aggtranstype => 'oid8' },
{ aggfnoid => 'max(float4)', aggtransfn => 'float4larger', { aggfnoid => 'max(float4)', aggtransfn => 'float4larger',
aggcombinefn => 'float4larger', aggsortop => '>(float4,float4)', aggcombinefn => 'float4larger', aggsortop => '>(float4,float4)',
aggtranstype => 'float4' }, aggtranstype => 'float4' },
@@ -178,6 +181,9 @@
{ aggfnoid => 'min(oid)', aggtransfn => 'oidsmaller', { aggfnoid => 'min(oid)', aggtransfn => 'oidsmaller',
aggcombinefn => 'oidsmaller', aggsortop => '<(oid,oid)', aggcombinefn => 'oidsmaller', aggsortop => '<(oid,oid)',
aggtranstype => 'oid' }, aggtranstype => 'oid' },
{ aggfnoid => 'min(oid8)', aggtransfn => 'oid8smaller',
aggcombinefn => 'oid8smaller', aggsortop => '<(oid8,oid8)',
aggtranstype => 'oid8' },
{ aggfnoid => 'min(float4)', aggtransfn => 'float4smaller', { aggfnoid => 'min(float4)', aggtransfn => 'float4smaller',
aggcombinefn => 'float4smaller', aggsortop => '<(float4,float4)', aggcombinefn => 'float4smaller', aggsortop => '<(float4,float4)',
aggtranstype => 'float4' }, aggtranstype => 'float4' },

View File

@@ -180,6 +180,24 @@
{ amopfamily => 'btree/oid_ops', amoplefttype => 'oid', amoprighttype => 'oid', { amopfamily => 'btree/oid_ops', amoplefttype => 'oid', amoprighttype => 'oid',
amopstrategy => '5', amopopr => '>(oid,oid)', amopmethod => 'btree' }, 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 # btree xid8_ops
{ amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8', { amopfamily => 'btree/xid8_ops', amoplefttype => 'xid8',
@@ -974,6 +992,11 @@
{ amopfamily => 'hash/oid_ops', amoplefttype => 'oid', amoprighttype => 'oid', { amopfamily => 'hash/oid_ops', amoplefttype => 'oid', amoprighttype => 'oid',
amopstrategy => '1', amopopr => '=(oid,oid)', amopmethod => 'hash' }, 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 # oidvector_ops
{ amopfamily => 'hash/oidvector_ops', amoplefttype => 'oidvector', { amopfamily => 'hash/oidvector_ops', amoplefttype => 'oidvector',
amoprighttype => 'oidvector', amopstrategy => '1', amoprighttype => 'oidvector', amopstrategy => '1',

View File

@@ -213,6 +213,14 @@
amprocrighttype => 'oid', amprocnum => '4', amproc => 'btequalimage' }, amprocrighttype => 'oid', amprocnum => '4', amproc => 'btequalimage' },
{ amprocfamily => 'btree/oid_ops', amproclefttype => 'oid', { amprocfamily => 'btree/oid_ops', amproclefttype => 'oid',
amprocrighttype => 'oid', amprocnum => '6', amproc => 'btoidskipsupport' }, 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', { amprocfamily => 'btree/oidvector_ops', amproclefttype => 'oidvector',
amprocrighttype => 'oidvector', amprocnum => '1', amprocrighttype => 'oidvector', amprocnum => '1',
amproc => 'btoidvectorcmp' }, amproc => 'btoidvectorcmp' },
@@ -432,6 +440,10 @@
amprocrighttype => 'xid8', amprocnum => '1', amproc => 'hashxid8' }, amprocrighttype => 'xid8', amprocnum => '1', amproc => 'hashxid8' },
{ amprocfamily => 'hash/xid8_ops', amproclefttype => 'xid8', { amprocfamily => 'hash/xid8_ops', amproclefttype => 'xid8',
amprocrighttype => 'xid8', amprocnum => '2', amproc => 'hashxid8extended' }, 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', { amprocfamily => 'hash/cid_ops', amproclefttype => 'cid',
amprocrighttype => 'cid', amprocnum => '1', amproc => 'hashcid' }, amprocrighttype => 'cid', amprocnum => '1', amproc => 'hashcid' },
{ amprocfamily => 'hash/cid_ops', amproclefttype => 'cid', { amprocfamily => 'hash/cid_ops', amproclefttype => 'cid',

View File

@@ -296,6 +296,20 @@
{ castsource => 'regdatabase', casttarget => 'int4', castfunc => '0', { castsource => 'regdatabase', casttarget => 'int4', castfunc => '0',
castcontext => 'a', castmethod => 'b' }, 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 # String category
{ castsource => 'text', casttarget => 'bpchar', castfunc => '0', { castsource => 'text', casttarget => 'bpchar', castfunc => '0',
castcontext => 'i', castmethod => 'b' }, castcontext => 'i', castmethod => 'b' },

View File

@@ -177,6 +177,10 @@
opcintype => 'xid8' }, opcintype => 'xid8' },
{ opcmethod => 'btree', opcname => 'xid8_ops', opcfamily => 'btree/xid8_ops', { opcmethod => 'btree', opcname => 'xid8_ops', opcfamily => 'btree/xid8_ops',
opcintype => 'xid8' }, 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', { opcmethod => 'hash', opcname => 'cid_ops', opcfamily => 'hash/cid_ops',
opcintype => 'cid' }, opcintype => 'cid' },
{ opcmethod => 'hash', opcname => 'tid_ops', opcfamily => 'hash/tid_ops', { opcmethod => 'hash', opcname => 'tid_ops', opcfamily => 'hash/tid_ops',

View File

@@ -3460,4 +3460,30 @@
oprcode => 'multirange_after_multirange', oprrest => 'multirangesel', oprcode => 'multirange_after_multirange', oprrest => 'multirangesel',
oprjoin => 'scalargtjoinsel' }, 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' },
] ]

View File

@@ -116,6 +116,10 @@
opfmethod => 'hash', opfname => 'xid8_ops' }, opfmethod => 'hash', opfname => 'xid8_ops' },
{ oid => '5067', { oid => '5067',
opfmethod => 'btree', opfname => 'xid8_ops' }, opfmethod => 'btree', opfname => 'xid8_ops' },
{ oid => '8278',
opfmethod => 'hash', opfname => 'oid8_ops' },
{ oid => '8279',
opfmethod => 'btree', opfname => 'oid8_ops' },
{ oid => '2226', { oid => '2226',
opfmethod => 'hash', opfname => 'cid_ops' }, opfmethod => 'hash', opfname => 'cid_ops' },
{ oid => '2227', { oid => '2227',

View File

@@ -1046,6 +1046,15 @@
{ oid => '6405', descr => 'skip support', { oid => '6405', descr => 'skip support',
proname => 'btoidskipsupport', prorettype => 'void', proname => 'btoidskipsupport', prorettype => 'void',
proargtypes => 'internal', prosrc => 'btoidskipsupport' }, 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', { oid => '404', descr => 'less-equal-greater',
proname => 'btoidvectorcmp', proleakproof => 't', prorettype => 'int4', proname => 'btoidvectorcmp', proleakproof => 't', prorettype => 'int4',
proargtypes => 'oidvector oidvector', prosrc => 'btoidvectorcmp' }, proargtypes => 'oidvector oidvector', prosrc => 'btoidvectorcmp' },
@@ -12619,4 +12628,59 @@
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}', 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' }, 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' },
] ]

View File

@@ -700,4 +700,9 @@
typreceive => 'brin_minmax_multi_summary_recv', typreceive => 'brin_minmax_multi_summary_recv',
typsend => 'brin_minmax_multi_summary_send', typalign => 'i', typsend => 'brin_minmax_multi_summary_send', typalign => 'i',
typstorage => 'x', typcollation => 'default' }, 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' },
] ]

View File

@@ -273,6 +273,7 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena *datum);
#define PG_GETARG_CHAR(n) DatumGetChar(PG_GETARG_DATUM(n)) #define PG_GETARG_CHAR(n) DatumGetChar(PG_GETARG_DATUM(n))
#define PG_GETARG_BOOL(n) DatumGetBool(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_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_POINTER(n) DatumGetPointer(PG_GETARG_DATUM(n))
#define PG_GETARG_CSTRING(n) DatumGetCString(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_GETARG_NAME(n) DatumGetName(PG_GETARG_DATUM(n))
@@ -358,6 +359,7 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena *datum);
#define PG_RETURN_CHAR(x) return CharGetDatum(x) #define PG_RETURN_CHAR(x) return CharGetDatum(x)
#define PG_RETURN_BOOL(x) return BoolGetDatum(x) #define PG_RETURN_BOOL(x) return BoolGetDatum(x)
#define PG_RETURN_OID(x) return ObjectIdGetDatum(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_POINTER(x) return PointerGetDatum(x)
#define PG_RETURN_CSTRING(x) return CStringGetDatum(x) #define PG_RETURN_CSTRING(x) return CStringGetDatum(x)
#define PG_RETURN_NAME(x) return NameGetDatum(x) #define PG_RETURN_NAME(x) return NameGetDatum(x)

View File

@@ -264,6 +264,26 @@ ObjectIdGetDatum(Oid X)
return (Datum) 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 * DatumGetTransactionId
* Returns transaction identifier value of a datum. * Returns transaction identifier value of a datum.

View File

@@ -65,6 +65,16 @@ WHERE hashoid(v)::bit(32) != hashoidextended(v, 0)::bit(32)
-------+----------+-----------+----------- -------+----------+-----------+-----------
(0 rows) (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, SELECT v as value, hashchar(v)::bit(32) as standard,
hashcharextended(v, 0)::bit(32) as extended0, hashcharextended(v, 0)::bit(32) as extended0,
hashcharextended(v, 1)::bit(32) as extended1 hashcharextended(v, 1)::bit(32) as extended1

View File

@@ -0,0 +1,368 @@
--
-- 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;

View File

@@ -880,6 +880,13 @@ bytea(integer)
bytea(bigint) bytea(bigint)
bytea_larger(bytea,bytea) bytea_larger(bytea,bytea)
bytea_smaller(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. -- Check that functions without argument are not marked as leakproof.
SELECT p1.oid::regprocedure SELECT p1.oid::regprocedure
FROM pg_proc p1 JOIN pg_namespace pn FROM pg_proc p1 JOIN pg_namespace pn

View File

@@ -702,6 +702,7 @@ CREATE TABLE tab_core_types AS SELECT
'abc'::refcursor, 'abc'::refcursor,
'1 2'::int2vector, '1 2'::int2vector,
'1 2'::oidvector, '1 2'::oidvector,
'1234'::oid8,
format('%I=UC/%I', USER, USER)::aclitem AS aclitem, format('%I=UC/%I', USER, USER)::aclitem AS aclitem,
'a fat cat sat on a mat and ate a fat rat'::tsvector, 'a fat cat sat on a mat and ate a fat rat'::tsvector,
'fat & rat'::tsquery, 'fat & rat'::tsquery,

View File

@@ -28,7 +28,7 @@ test: strings md5 numerology point lseg line box path polygon circle date time t
# geometry depends on point, lseg, line, box, path, polygon, circle # geometry depends on point, lseg, line, box, path, polygon, circle
# horology depends on date, time, timetz, timestamp, timestamptz, interval # 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 # Load huge amounts of data

View File

@@ -48,6 +48,13 @@ FROM (VALUES (0), (1), (17), (42), (550273), (207112489)) x(v)
WHERE hashoid(v)::bit(32) != hashoidextended(v, 0)::bit(32) WHERE hashoid(v)::bit(32) != hashoidextended(v, 0)::bit(32)
OR hashoid(v)::bit(32) = hashoidextended(v, 1)::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, SELECT v as value, hashchar(v)::bit(32) as standard,
hashcharextended(v, 0)::bit(32) as extended0, hashcharextended(v, 0)::bit(32) as extended0,
hashcharextended(v, 1)::bit(32) as extended1 hashcharextended(v, 1)::bit(32) as extended1

View File

@@ -0,0 +1,87 @@
--
-- 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;

View File

@@ -530,6 +530,7 @@ CREATE TABLE tab_core_types AS SELECT
'abc'::refcursor, 'abc'::refcursor,
'1 2'::int2vector, '1 2'::int2vector,
'1 2'::oidvector, '1 2'::oidvector,
'1234'::oid8,
format('%I=UC/%I', USER, USER)::aclitem AS aclitem, format('%I=UC/%I', USER, USER)::aclitem AS aclitem,
'a fat cat sat on a mat and ate a fat rat'::tsvector, 'a fat cat sat on a mat and ate a fat rat'::tsvector,
'fat & rat'::tsquery, 'fat & rat'::tsquery,