From 0778ce89d27f18f9af19fbe6d98f2f1ff34a5d61 Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Thu, 18 Nov 2010 14:07:15 -0300
Subject: [PATCH] Add pg_describe_object function

This function is useful to obtain textual descriptions of objects as
stored in pg_depend.
---
 doc/src/sgml/func.sgml           |   12 ++++++++++++
 src/backend/catalog/dependency.c |   33 +++++++++++++++++++++++++++++++++
 src/include/catalog/catversion.h |    2 +-
 src/include/catalog/pg_proc.h    |    2 ++
 4 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 1be9f90..11dd3bc 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -12848,6 +12848,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
        <entry>get the set of database OIDs that have objects in the tablespace</entry>
       </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>
        <entry><literal><function>pg_typeof(<parameter>any</parameter>)</function></literal></entry>
        <entry><type>regtype</type></entry>
        <entry>get the data type of any value</entry>
@@ -12941,6 +12946,13 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
   </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>
    <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
    dynamically constructing SQL queries.  The function is declared as
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index bb14a43..9727e6a 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -186,6 +186,9 @@ static void getRelationDescription(StringInfo buffer, Oid relid);
 static void getOpFamilyDescription(StringInfo buffer, Oid opfid);
 
 
+/* this doesn't really need to appear in any header file */
+Datum	pg_describe_object(PG_FUNCTION_ARGS);
+
 /*
  * performDeletion: attempt to drop the specified object.  If CASCADE
  * behavior is specified, also drop any dependent objects (recursively).
@@ -2807,3 +2810,33 @@ getOpFamilyDescription(StringInfo buffer, Oid opfid)
 	ReleaseSysCache(amTup);
 	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);
+	ObjectAddress        address;
+	char   *description = NULL;
+
+	/* 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);
+
+	if (!description)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+				 errmsg("invalid object specification")));
+
+	PG_RETURN_TEXT_P(cstring_to_text(description));
+}
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index d6b6c71..e168805 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	201011151
+#define CATALOG_VERSION_NO	201011181
 
 #endif
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 8e5f502..3e17eff 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -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_ ));
 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_ ));
 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_ ));
-- 
1.7.2.3

