OSDN Git Service

Add pg_describe_object function
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 18 Nov 2010 19:33:48 +0000 (16:33 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 18 Nov 2010 20:06:19 +0000 (17:06 -0300)
This function is useful to obtain textual descriptions of objects as
stored in pg_depend.

doc/src/sgml/func.sgml
src/backend/catalog/dependency.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h
src/include/utils/builtins.h

index 1be9f90..11dd3bc 100644 (file)
@@ -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
index bb14a43..c4ccb5f 100644 (file)
@@ -1982,6 +1982,12 @@ free_object_addresses(ObjectAddresses *addrs)
 ObjectClass
 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)
        {
                case RelationRelationId:
@@ -1989,111 +1995,84 @@ getObjectClass(const ObjectAddress *object)
                        return OCLASS_CLASS;
 
                case ProcedureRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_PROC;
 
                case TypeRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_TYPE;
 
                case CastRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_CAST;
 
                case ConstraintRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_CONSTRAINT;
 
                case ConversionRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_CONVERSION;
 
                case AttrDefaultRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_DEFAULT;
 
                case LanguageRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_LANGUAGE;
 
                case LargeObjectRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_LARGEOBJECT;
 
                case OperatorRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_OPERATOR;
 
                case OperatorClassRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_OPCLASS;
 
                case OperatorFamilyRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_OPFAMILY;
 
                case AccessMethodOperatorRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_AMOP;
 
                case AccessMethodProcedureRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_AMPROC;
 
                case RewriteRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_REWRITE;
 
                case TriggerRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_TRIGGER;
 
                case NamespaceRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_SCHEMA;
 
                case TSParserRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_TSPARSER;
 
                case TSDictionaryRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_TSDICT;
 
                case TSTemplateRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_TSTEMPLATE;
 
                case TSConfigRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_TSCONFIG;
 
                case AuthIdRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_ROLE;
 
                case DatabaseRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_DATABASE;
 
                case TableSpaceRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_TBLSPACE;
 
                case ForeignDataWrapperRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_FDW;
 
                case ForeignServerRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_FOREIGN_SERVER;
 
                case UserMappingRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_USER_MAPPING;
 
                case DefaultAclRelationId:
-                       Assert(object->objectSubId == 0);
                        return OCLASS_DEFACL;
        }
 
@@ -2807,3 +2786,27 @@ 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);
+       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));
+}
index d6b6c71..e168805 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     201011151
+#define CATALOG_VERSION_NO     201011181
 
 #endif
index 8e5f502..3e17eff 100644 (file)
@@ -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_ ));
index f4b2a96..020ce3c 100644 (file)
@@ -1045,6 +1045,9 @@ extern Datum window_nth_value(PG_FUNCTION_ARGS);
 /* access/transam/twophase.c */
 extern Datum pg_prepared_xact(PG_FUNCTION_ARGS);
 
+/* catalogs/dependency.c */
+extern Datum pg_describe_object(PG_FUNCTION_ARGS);
+
 /* commands/constraint.c */
 extern Datum unique_key_recheck(PG_FUNCTION_ARGS);