Commit 6cc2deb8 authored by Alvaro Herrera's avatar Alvaro Herrera

Add pg_describe_object function

This function is useful to obtain textual descriptions of objects as
stored in pg_depend.
parent 48c348f8
...@@ -12847,6 +12847,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); ...@@ -12847,6 +12847,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
<entry><type>setof oid</type></entry> <entry><type>setof oid</type></entry>
<entry>get the set of database OIDs that have objects in the tablespace</entry> <entry>get the set of database OIDs that have objects in the tablespace</entry>
</row> </row>
<row>
<entry><literal><function>pg_describe_object(<parameter>catalog_id</parameter>, <parameter>object_id</parameter>, <parameter>object_sub_id</parameter>)</function>)</literal></entry>
<entry><type>text</type></entry>
<entry>get description of a database object</entry>
</row>
<row> <row>
<entry><literal><function>pg_typeof(<parameter>any</parameter>)</function></literal></entry> <entry><literal><function>pg_typeof(<parameter>any</parameter>)</function></literal></entry>
<entry><type>regtype</type></entry> <entry><type>regtype</type></entry>
...@@ -12940,6 +12945,13 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); ...@@ -12940,6 +12945,13 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
<structname>pg_class</> catalogs. <structname>pg_class</> catalogs.
</para> </para>
<para>
<function>pg_describe_object</function> returns a description of a database
object specified by catalog OID, object OID and a (possibly zero) sub-object ID.
This is useful to determine the identity of an object as stored in the
<structname>pg_depend</structname> catalog.
</para>
<para> <para>
<function>pg_typeof</function> returns the OID of the data type of the <function>pg_typeof</function> returns the OID of the data type of the
value that is passed to it. This can be helpful for troubleshooting or value that is passed to it. This can be helpful for troubleshooting or
......
...@@ -1982,6 +1982,12 @@ free_object_addresses(ObjectAddresses *addrs) ...@@ -1982,6 +1982,12 @@ free_object_addresses(ObjectAddresses *addrs)
ObjectClass ObjectClass
getObjectClass(const ObjectAddress *object) getObjectClass(const ObjectAddress *object)
{ {
/* only pg_class entries can have nonzero objectSubId */
if (object->classId != RelationRelationId &&
object->objectSubId != 0)
elog(ERROR, "invalid objectSubId 0 for object class %u",
object->classId);
switch (object->classId) switch (object->classId)
{ {
case RelationRelationId: case RelationRelationId:
...@@ -1989,111 +1995,84 @@ getObjectClass(const ObjectAddress *object) ...@@ -1989,111 +1995,84 @@ getObjectClass(const ObjectAddress *object)
return OCLASS_CLASS; return OCLASS_CLASS;
case ProcedureRelationId: case ProcedureRelationId:
Assert(object->objectSubId == 0);
return OCLASS_PROC; return OCLASS_PROC;
case TypeRelationId: case TypeRelationId:
Assert(object->objectSubId == 0);
return OCLASS_TYPE; return OCLASS_TYPE;
case CastRelationId: case CastRelationId:
Assert(object->objectSubId == 0);
return OCLASS_CAST; return OCLASS_CAST;
case ConstraintRelationId: case ConstraintRelationId:
Assert(object->objectSubId == 0);
return OCLASS_CONSTRAINT; return OCLASS_CONSTRAINT;
case ConversionRelationId: case ConversionRelationId:
Assert(object->objectSubId == 0);
return OCLASS_CONVERSION; return OCLASS_CONVERSION;
case AttrDefaultRelationId: case AttrDefaultRelationId:
Assert(object->objectSubId == 0);
return OCLASS_DEFAULT; return OCLASS_DEFAULT;
case LanguageRelationId: case LanguageRelationId:
Assert(object->objectSubId == 0);
return OCLASS_LANGUAGE; return OCLASS_LANGUAGE;
case LargeObjectRelationId: case LargeObjectRelationId:
Assert(object->objectSubId == 0);
return OCLASS_LARGEOBJECT; return OCLASS_LARGEOBJECT;
case OperatorRelationId: case OperatorRelationId:
Assert(object->objectSubId == 0);
return OCLASS_OPERATOR; return OCLASS_OPERATOR;
case OperatorClassRelationId: case OperatorClassRelationId:
Assert(object->objectSubId == 0);
return OCLASS_OPCLASS; return OCLASS_OPCLASS;
case OperatorFamilyRelationId: case OperatorFamilyRelationId:
Assert(object->objectSubId == 0);
return OCLASS_OPFAMILY; return OCLASS_OPFAMILY;
case AccessMethodOperatorRelationId: case AccessMethodOperatorRelationId:
Assert(object->objectSubId == 0);
return OCLASS_AMOP; return OCLASS_AMOP;
case AccessMethodProcedureRelationId: case AccessMethodProcedureRelationId:
Assert(object->objectSubId == 0);
return OCLASS_AMPROC; return OCLASS_AMPROC;
case RewriteRelationId: case RewriteRelationId:
Assert(object->objectSubId == 0);
return OCLASS_REWRITE; return OCLASS_REWRITE;
case TriggerRelationId: case TriggerRelationId:
Assert(object->objectSubId == 0);
return OCLASS_TRIGGER; return OCLASS_TRIGGER;
case NamespaceRelationId: case NamespaceRelationId:
Assert(object->objectSubId == 0);
return OCLASS_SCHEMA; return OCLASS_SCHEMA;
case TSParserRelationId: case TSParserRelationId:
Assert(object->objectSubId == 0);
return OCLASS_TSPARSER; return OCLASS_TSPARSER;
case TSDictionaryRelationId: case TSDictionaryRelationId:
Assert(object->objectSubId == 0);
return OCLASS_TSDICT; return OCLASS_TSDICT;
case TSTemplateRelationId: case TSTemplateRelationId:
Assert(object->objectSubId == 0);
return OCLASS_TSTEMPLATE; return OCLASS_TSTEMPLATE;
case TSConfigRelationId: case TSConfigRelationId:
Assert(object->objectSubId == 0);
return OCLASS_TSCONFIG; return OCLASS_TSCONFIG;
case AuthIdRelationId: case AuthIdRelationId:
Assert(object->objectSubId == 0);
return OCLASS_ROLE; return OCLASS_ROLE;
case DatabaseRelationId: case DatabaseRelationId:
Assert(object->objectSubId == 0);
return OCLASS_DATABASE; return OCLASS_DATABASE;
case TableSpaceRelationId: case TableSpaceRelationId:
Assert(object->objectSubId == 0);
return OCLASS_TBLSPACE; return OCLASS_TBLSPACE;
case ForeignDataWrapperRelationId: case ForeignDataWrapperRelationId:
Assert(object->objectSubId == 0);
return OCLASS_FDW; return OCLASS_FDW;
case ForeignServerRelationId: case ForeignServerRelationId:
Assert(object->objectSubId == 0);
return OCLASS_FOREIGN_SERVER; return OCLASS_FOREIGN_SERVER;
case UserMappingRelationId: case UserMappingRelationId:
Assert(object->objectSubId == 0);
return OCLASS_USER_MAPPING; return OCLASS_USER_MAPPING;
case DefaultAclRelationId: case DefaultAclRelationId:
Assert(object->objectSubId == 0);
return OCLASS_DEFACL; return OCLASS_DEFACL;
} }
...@@ -2807,3 +2786,27 @@ getOpFamilyDescription(StringInfo buffer, Oid opfid) ...@@ -2807,3 +2786,27 @@ getOpFamilyDescription(StringInfo buffer, Oid opfid)
ReleaseSysCache(amTup); ReleaseSysCache(amTup);
ReleaseSysCache(opfTup); ReleaseSysCache(opfTup);
} }
/*
* SQL-level callable version of getObjectDescription
*/
Datum
pg_describe_object(PG_FUNCTION_ARGS)
{
Oid classid = PG_GETARG_OID(0);
Oid objid = PG_GETARG_OID(1);
int32 subobjid = PG_GETARG_INT32(2);
char *description = NULL;
ObjectAddress address;
/* for "pinned" items in pg_depend, return null */
if (!OidIsValid(classid) && !OidIsValid(objid))
PG_RETURN_NULL();
address.classId = classid;
address.objectId = objid;
address.objectSubId = subobjid;
description = getObjectDescription(&address);
PG_RETURN_TEXT_P(cstring_to_text(description));
}
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 201011151 #define CATALOG_VERSION_NO 201011181
#endif #endif
...@@ -3333,6 +3333,8 @@ DESCR("view system lock information"); ...@@ -3333,6 +3333,8 @@ DESCR("view system lock information");
DATA(insert OID = 1065 ( pg_prepared_xact PGNSP PGUID 12 1 1000 0 f f f t t v 0 0 2249 "" "{28,25,1184,26,26}" "{o,o,o,o,o}" "{transaction,gid,prepared,ownerid,dbid}" _null_ pg_prepared_xact _null_ _null_ _null_ )); DATA(insert OID = 1065 ( pg_prepared_xact PGNSP PGUID 12 1 1000 0 f f f t t v 0 0 2249 "" "{28,25,1184,26,26}" "{o,o,o,o,o}" "{transaction,gid,prepared,ownerid,dbid}" _null_ pg_prepared_xact _null_ _null_ _null_ ));
DESCR("view two-phase transactions"); DESCR("view two-phase transactions");
DATA(insert OID = 3537 ( pg_describe_object PGNSP PGUID 12 1 0 0 f f f t f s 3 0 25 "26 26 23" _null_ _null_ _null_ _null_ pg_describe_object _null_ _null_ _null_ ));
DATA(insert OID = 2079 ( pg_table_is_visible PGNSP PGUID 12 1 0 0 f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_table_is_visible _null_ _null_ _null_ )); DATA(insert OID = 2079 ( pg_table_is_visible PGNSP PGUID 12 1 0 0 f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_table_is_visible _null_ _null_ _null_ ));
DESCR("is table visible in search path?"); DESCR("is table visible in search path?");
DATA(insert OID = 2080 ( pg_type_is_visible PGNSP PGUID 12 1 0 0 f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_type_is_visible _null_ _null_ _null_ )); DATA(insert OID = 2080 ( pg_type_is_visible PGNSP PGUID 12 1 0 0 f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_type_is_visible _null_ _null_ _null_ ));
......
...@@ -1045,6 +1045,9 @@ extern Datum window_nth_value(PG_FUNCTION_ARGS); ...@@ -1045,6 +1045,9 @@ extern Datum window_nth_value(PG_FUNCTION_ARGS);
/* access/transam/twophase.c */ /* access/transam/twophase.c */
extern Datum pg_prepared_xact(PG_FUNCTION_ARGS); extern Datum pg_prepared_xact(PG_FUNCTION_ARGS);
/* catalogs/dependency.c */
extern Datum pg_describe_object(PG_FUNCTION_ARGS);
/* commands/constraint.c */ /* commands/constraint.c */
extern Datum unique_key_recheck(PG_FUNCTION_ARGS); extern Datum unique_key_recheck(PG_FUNCTION_ARGS);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment