]> granicus.if.org Git - postgresql/commitdiff
Repair bug noticed by Deepak Bhole: a shell type should have a dependency
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 8 Jan 2003 21:40:49 +0000 (21:40 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 8 Jan 2003 21:40:49 +0000 (21:40 +0000)
on its namespace, so that it will go away if the schema is dropped.

src/backend/catalog/pg_type.c
src/include/catalog/pg_type.h

index d43c1edeeedd3e831e3c701cfb83f3b9dcc01e63..8a8db49ddeaa23f7102b08574927d7f896b18689 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.82 2002/09/04 20:31:14 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.82.2.1 2003/01/08 21:40:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -105,6 +105,21 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
 
        CatalogUpdateIndexes(pg_type_desc, tup);
 
+       /*
+        * Create dependencies.  We can/must skip this in bootstrap mode.
+        */
+       if (!IsBootstrapProcessingMode())
+               GenerateTypeDependencies(typeNamespace,
+                                                                typoid,
+                                                                InvalidOid,
+                                                                0,
+                                                                InvalidOid,
+                                                                InvalidOid,
+                                                                InvalidOid,
+                                                                InvalidOid,
+                                                                NULL,
+                                                                false);
+
        /*
         * clean up and return the type-oid
         */
@@ -129,7 +144,7 @@ Oid
 TypeCreate(const char *typeName,
                   Oid typeNamespace,
                   Oid assignedTypeOid,
-                  Oid relationOid,             /* only for 'c'atalog typeType */
+                  Oid relationOid,             /* only for 'c'atalog types */
                   char relationKind,   /* ditto */
                   int16 internalSize,
                   char typeType,
@@ -139,7 +154,7 @@ TypeCreate(const char *typeName,
                   Oid elementType,
                   Oid baseType,
                   const char *defaultTypeValue,                /* human readable rep */
-                  const char *defaultTypeBin,  /* cooked rep */
+                  char *defaultTypeBin,        /* cooked rep */
                   bool passedByValue,
                   char alignment,
                   char storage,
@@ -149,6 +164,7 @@ TypeCreate(const char *typeName,
 {
        Relation        pg_type_desc;
        Oid                     typeObjectId;
+       bool            rebuildDeps = false;
        HeapTuple       tup;
        char            nulls[Natts_pg_type];
        char            replaces[Natts_pg_type];
@@ -268,6 +284,8 @@ TypeCreate(const char *typeName,
                simple_heap_update(pg_type_desc, &tup->t_self, tup);
 
                typeObjectId = HeapTupleGetOid(tup);
+
+               rebuildDeps = true;             /* get rid of shell type's dependencies */
        }
        else
        {
@@ -290,88 +308,135 @@ TypeCreate(const char *typeName,
         * Create dependencies.  We can/must skip this in bootstrap mode.
         */
        if (!IsBootstrapProcessingMode())
+               GenerateTypeDependencies(typeNamespace,
+                                                                typeObjectId,
+                                                                relationOid,
+                                                                relationKind,
+                                                                inputProcedure,
+                                                                outputProcedure,
+                                                                elementType,
+                                                                baseType,
+                                                                (defaultTypeBin ?
+                                                                 stringToNode(defaultTypeBin) :
+                                                                 (void *) NULL),
+                                                                rebuildDeps);
+
+       /*
+        * finish up
+        */
+       heap_close(pg_type_desc, RowExclusiveLock);
+
+       return typeObjectId;
+}
+
+/*
+ * GenerateTypeDependencies: build the dependencies needed for a type
+ *
+ * If rebuild is true, we remove existing dependencies and rebuild them
+ * from scratch.  This is needed for ALTER TYPE, and also when replacing
+ * a shell type.
+ *
+ * NOTE: a shell type will have a dependency to its namespace, and no others.
+ */
+void
+GenerateTypeDependencies(Oid typeNamespace,
+                                                Oid typeObjectId,
+                                                Oid relationOid,               /* only for 'c'atalog types */
+                                                char relationKind,             /* ditto */
+                                                Oid inputProcedure,
+                                                Oid outputProcedure,
+                                                Oid elementType,
+                                                Oid baseType,
+                                                Node *defaultExpr,
+                                                bool rebuild)
+{
+       ObjectAddress myself,
+                               referenced;
+
+       if (rebuild)
+               deleteDependencyRecordsFor(RelOid_pg_type,
+                                                                  typeObjectId);
+
+       myself.classId = RelOid_pg_type;
+       myself.objectId = typeObjectId;
+       myself.objectSubId = 0;
+
+       /* dependency on namespace */
+       /* skip for relation rowtype, since we have indirect dependency */
+       if (!OidIsValid(relationOid))
+       {
+               referenced.classId = get_system_catalog_relid(NamespaceRelationName);
+               referenced.objectId = typeNamespace;
+               referenced.objectSubId = 0;
+               recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+       }
+
+       /* Normal dependencies on the I/O functions */
+       if (OidIsValid(inputProcedure))
        {
-               ObjectAddress myself,
-                                       referenced;
-
-               myself.classId = RelOid_pg_type;
-               myself.objectId = typeObjectId;
-               myself.objectSubId = 0;
-
-               /* dependency on namespace */
-               /* skip for relation rowtype, since we have indirect dependency */
-               if (!OidIsValid(relationOid))
-               {
-                       referenced.classId = get_system_catalog_relid(NamespaceRelationName);
-                       referenced.objectId = typeNamespace;
-                       referenced.objectSubId = 0;
-                       recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-               }
-
-               /* Normal dependencies on the I/O functions */
                referenced.classId = RelOid_pg_proc;
                referenced.objectId = inputProcedure;
                referenced.objectSubId = 0;
                recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+       }
 
+       if (OidIsValid(outputProcedure))
+       {
                referenced.classId = RelOid_pg_proc;
                referenced.objectId = outputProcedure;
                referenced.objectSubId = 0;
                recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+       }
 
-               /*
-                * If the type is a rowtype for a relation, mark it as internally
-                * dependent on the relation, *unless* it is a stand-alone
-                * composite type relation. For the latter case, we have to
-                * reverse the dependency.
-                *
-                * In the former case, this allows the type to be auto-dropped when
-                * the relation is, and not otherwise. And in the latter, of
-                * course we get the opposite effect.
-                */
-               if (OidIsValid(relationOid))
-               {
-                       referenced.classId = RelOid_pg_class;
-                       referenced.objectId = relationOid;
-                       referenced.objectSubId = 0;
-
-                       if (relationKind != RELKIND_COMPOSITE_TYPE)
-                               recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
-                       else
-                               recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
-               }
+       /*
+        * If the type is a rowtype for a relation, mark it as internally
+        * dependent on the relation, *unless* it is a stand-alone
+        * composite type relation. For the latter case, we have to
+        * reverse the dependency.
+        *
+        * In the former case, this allows the type to be auto-dropped when
+        * the relation is, and not otherwise. And in the latter, of
+        * course we get the opposite effect.
+        */
+       if (OidIsValid(relationOid))
+       {
+               referenced.classId = RelOid_pg_class;
+               referenced.objectId = relationOid;
+               referenced.objectSubId = 0;
 
-               /*
-                * If the type is an array type, mark it auto-dependent on the
-                * base type.  (This is a compromise between the typical case
-                * where the array type is automatically generated and the case
-                * where it is manually created: we'd prefer INTERNAL for the
-                * former case and NORMAL for the latter.)
-                */
-               if (OidIsValid(elementType))
-               {
-                       referenced.classId = RelOid_pg_type;
-                       referenced.objectId = elementType;
-                       referenced.objectSubId = 0;
-                       recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
-               }
-
-               /* Normal dependency from a domain to its base type. */
-               if (OidIsValid(baseType))
-               {
-                       referenced.classId = RelOid_pg_type;
-                       referenced.objectId = baseType;
-                       referenced.objectSubId = 0;
-                       recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-               }
+               if (relationKind != RELKIND_COMPOSITE_TYPE)
+                       recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
+               else
+                       recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
        }
 
        /*
-        * finish up
+        * If the type is an array type, mark it auto-dependent on the
+        * base type.  (This is a compromise between the typical case
+        * where the array type is automatically generated and the case
+        * where it is manually created: we'd prefer INTERNAL for the
+        * former case and NORMAL for the latter.)
         */
-       heap_close(pg_type_desc, RowExclusiveLock);
+       if (OidIsValid(elementType))
+       {
+               referenced.classId = RelOid_pg_type;
+               referenced.objectId = elementType;
+               referenced.objectSubId = 0;
+               recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
+       }
 
-       return typeObjectId;
+       /* Normal dependency from a domain to its base type. */
+       if (OidIsValid(baseType))
+       {
+               referenced.classId = RelOid_pg_type;
+               referenced.objectId = baseType;
+               referenced.objectSubId = 0;
+               recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+       }
+
+       /* Normal dependency on the default expression. */
+       if (defaultExpr)
+               recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL);
 }
 
 /*
index 06ac2f340a6d77dbafcf21e6d9e09dfea4464390..31bde74513a4d66a70fec7038f23f0fda4513a51 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_type.h,v 1.134 2002/09/24 21:26:44 tgl Exp $
+ * $Id: pg_type.h,v 1.134.2.1 2003/01/08 21:40:49 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -19,6 +19,8 @@
 #ifndef PG_TYPE_H
 #define PG_TYPE_H
 
+#include "nodes/nodes.h"
+
 /* ----------------
  *             postgres.h contains the system type definitions and the
  *             CATALOG(), BOOTSTRAP and DATA() sugar words so this file
@@ -537,7 +539,7 @@ DATA(insert OID = 2282 ( opaque                     PGNSP PGUID  4 t p t \054 0 0 opaque_in opaque
  */
 extern Oid     TypeShellMake(const char *typeName, Oid typeNamespace);
 
-extern Oid TypeCreate(const char *typeName,
+extern Oid     TypeCreate(const char *typeName,
                   Oid typeNamespace,
                   Oid assignedTypeOid,
                   Oid relationOid,
@@ -550,7 +552,7 @@ extern Oid TypeCreate(const char *typeName,
                   Oid elementType,
                   Oid baseType,
                   const char *defaultTypeValue,
-                  const char *defaultTypeBin,
+                  char *defaultTypeBin,
                   bool passedByValue,
                   char alignment,
                   char storage,
@@ -558,9 +560,20 @@ extern Oid TypeCreate(const char *typeName,
                   int32 typNDims,
                   bool typeNotNull);
 
+extern void GenerateTypeDependencies(Oid typeNamespace,
+                                                                        Oid typeObjectId,
+                                                                        Oid relationOid,
+                                                                        char relationKind,
+                                                                        Oid inputProcedure,
+                                                                        Oid outputProcedure,
+                                                                        Oid elementType,
+                                                                        Oid baseType,
+                                                                        Node *defaultExpr,
+                                                                        bool rebuild);
 
 extern void TypeRename(const char *oldTypeName, Oid typeNamespace,
                   const char *newTypeName);
+
 extern char *makeArrayTypeName(const char *typeName);
 
 #endif   /* PG_TYPE_H */