diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index ceda48e0fc..321d9c1fb1 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -18740,6 +18740,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_get_object_address + + pg_is_user_object + + lists functions related to database object identification and addressing. @@ -18768,6 +18772,14 @@ SELECT collation for ('foo' COLLATE "de_DE"); type text, object_names text[], object_args text[] get external representation of a database object's address + + pg_is_user_object(oid) + bool + + true if oid is the object which is created during + normal multi-user database operation. + + pg_get_object_address(type text, object_names text[], object_args text[]) classid oid, objid oid, objsubid integer diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index c5eea7af3f..7888e00d03 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -106,7 +106,7 @@ is_publishable_class(Oid relid, Form_pg_class reltuple) return reltuple->relkind == RELKIND_RELATION && !IsCatalogRelationOid(relid) && reltuple->relpersistence == RELPERSISTENCE_PERMANENT && - relid >= FirstNormalObjectId; + ObjectIsUserObject(relid); } /* diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c index 567eab1e01..e4f00fc309 100644 --- a/src/backend/utils/adt/json.c +++ b/src/backend/utils/adt/json.c @@ -204,7 +204,7 @@ json_categorize_type(Oid typoid, /* It's probably the general case ... */ *tcategory = JSONTYPE_OTHER; /* but let's look for a cast to json, if it's not built-in */ - if (typoid >= FirstNormalObjectId) + if (ObjectIsUserObject(typoid)) { Oid castfunc; CoercionPathType ctype; diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c index fea4335951..6869ea9954 100644 --- a/src/backend/utils/adt/jsonb.c +++ b/src/backend/utils/adt/jsonb.c @@ -690,7 +690,7 @@ jsonb_categorize_type(Oid typoid, * but first let's look for a cast to json (note: not to * jsonb) if it's not built-in. */ - if (typoid >= FirstNormalObjectId) + if (ObjectIsUserObject(typoid)) { Oid castfunc; CoercionPathType ctype; diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 158784474d..15b1ad13eb 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3202,6 +3202,16 @@ pg_get_function_arg_default(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(string_to_text(str)); } +/* + * Return true if the given oid is normal user object + */ +Datum +pg_is_user_object(PG_FUNCTION_ARGS) +{ + Oid oid = PG_GETARG_OID(0); + + PG_RETURN_BOOL(ObjectIsUserObject(oid)); +} /* * deparse_expression - General utility for deparsing expressions diff --git a/src/include/access/transam.h b/src/include/access/transam.h index 6a947b958b..afc3c24978 100644 --- a/src/include/access/transam.h +++ b/src/include/access/transam.h @@ -140,6 +140,9 @@ FullTransactionIdAdvance(FullTransactionId *dest) #define FirstBootstrapObjectId 12000 #define FirstNormalObjectId 16384 +/* Return true if the oid is assigned during normal multiuser operation */ +#define ObjectIsUserObject(oid) ((Oid) oid >= FirstNormalObjectId) + /* * VariableCache is a data structure in shared memory that is used to track * OID and XID assignment state. For largely historical reasons, there is diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index eb3c1a88d1..5c83f5f80f 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3637,6 +3637,10 @@ proname => 'pg_get_function_arg_default', provolatile => 's', prorettype => 'text', proargtypes => 'oid int4', prosrc => 'pg_get_function_arg_default' }, +{ oid => '4192', descr => 'identify normal user object', + proname => 'pg_is_user_object', provolatile => 's', + prorettype => 'bool', proargtypes => 'oid', + prosrc => 'pg_is_user_object' }, { oid => '1686', descr => 'list of SQL keywords', proname => 'pg_get_keywords', procost => '10', prorows => '400', diff --git a/src/test/regress/expected/object_address.out b/src/test/regress/expected/object_address.out index d6d1470156..c9f117ac38 100644 --- a/src/test/regress/expected/object_address.out +++ b/src/test/regress/expected/object_address.out @@ -492,6 +492,19 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, publication relation | | | addr_nsp.gentable in publication addr_pub | t (49 rows) +-- identity if the object is built-in or user-defined +SELECT pg_is_user_object('pg_class'::regclass); + pg_is_user_object +------------------- + f +(1 row) + +SELECT pg_is_user_object('trig'::regproc); + pg_is_user_object +------------------- + t +(1 row) + --- --- Cleanup resources --- diff --git a/src/test/regress/sql/object_address.sql b/src/test/regress/sql/object_address.sql index 8e06248eb5..3b8f0316fe 100644 --- a/src/test/regress/sql/object_address.sql +++ b/src/test/regress/sql/object_address.sql @@ -210,6 +210,10 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, pg_get_object_address(typ, nms, ioa.args) as addr2 ORDER BY addr1.classid, addr1.objid, addr1.objsubid; +-- identity if the object is built-in or user-defined +SELECT pg_is_user_object('pg_class'::regclass); +SELECT pg_is_user_object('trig'::regproc); + --- --- Cleanup resources ---