Repair bug noticed by Deepak Bhole: a shell type should have a dependency
authorTom Lane
Wed, 8 Jan 2003 21:40:39 +0000 (21:40 +0000)
committerTom Lane
Wed, 8 Jan 2003 21:40:39 +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/backend/commands/typecmds.c
src/include/catalog/pg_type.h

index 476bfa61be659e6a15531d6d5619d17b5603517a..66b6788eeef7f773928921e49a490535713df1f7 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.85 2002/12/06 05:00:10 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.86 2003/01/08 21:40:39 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,
@@ -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,7 +308,6 @@ TypeCreate(const char *typeName,
     * Create dependencies.  We can/must skip this in bootstrap mode.
     */
    if (!IsBootstrapProcessingMode())
-   {
        GenerateTypeDependencies(typeNamespace,
                                 typeObjectId,
                                 relationOid,
@@ -299,9 +316,10 @@ TypeCreate(const char *typeName,
                                 outputProcedure,
                                 elementType,
                                 baseType,
-                                defaultTypeBin,
-                                false);
-   }
+                                (defaultTypeBin ?
+                                 stringToNode(defaultTypeBin) :
+                                 (void *) NULL),
+                                rebuildDeps);
 
    /*
     * finish up
@@ -311,26 +329,30 @@ TypeCreate(const char *typeName,
    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 typeType */
-                        char relationKind,
+                        Oid relationOid,       /* only for 'c'atalog types */
+                        char relationKind,     /* ditto */
                         Oid inputProcedure,
                         Oid outputProcedure,
                         Oid elementType,
                         Oid baseType,
-                        char *defaultTypeBin,  /* cooked rep */
+                        Node *defaultExpr,
                         bool rebuild)
 {
    ObjectAddress myself,
                referenced;
 
-   /*
-    * If true, we need to remove all current dependencies that the type
-    * holds, and rebuild them from scratch.  This allows us to easily 
-    * implement alter type, and alter domain statements.
-    */
    if (rebuild)
        deleteDependencyRecordsFor(RelOid_pg_type,
                                   typeObjectId);
@@ -350,15 +372,21 @@ GenerateTypeDependencies(Oid typeNamespace,
    }
 
    /* 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(inputProcedure))
+   {
+       referenced.classId = RelOid_pg_proc;
+       referenced.objectId = inputProcedure;
+       referenced.objectSubId = 0;
+       recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+   }
 
-   referenced.classId = RelOid_pg_proc;
-   referenced.objectId = outputProcedure;
-   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
@@ -406,10 +434,9 @@ GenerateTypeDependencies(Oid typeNamespace,
        recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
    }
 
-   /* Dependency on the default expression */
-   if (defaultTypeBin)
-       recordDependencyOnExpr(&myself, stringToNode(defaultTypeBin),
-                              NIL, DEPENDENCY_NORMAL);
+   /* Normal dependency on the default expression. */
+   if (defaultExpr)
+       recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL);
 }
 
 /*
index bd29033c729b6c859fb8ea7512f04b73e360eb6b..7d4ff1f0b649368d49f71f79fbde5e9cb9b356b9 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.27 2003/01/06 00:31:44 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.28 2003/01/08 21:40:39 tgl Exp $
  *
  * DESCRIPTION
  *   The "DefineFoo" routines take the parse tree and pick out the
@@ -1012,12 +1012,12 @@ AlterDomainDefault(List *names, Node *defaultRaw)
    GenerateTypeDependencies(typTup->typnamespace,
                             domainoid,
                             typTup->typrelid,
-                            InvalidOid,
+                            0, /* relation kind is n/a */
                             typTup->typinput,
                             typTup->typoutput,
                             typTup->typelem,
                             typTup->typbasetype,
-                            nodeToString(defaultExpr),
+                            defaultExpr,
                             true); /* Rebuild is true */
 
    /* Clean up */
index dc8b9f617e0be80f219ea7397df0b45e0ced983d..fa19d84508a2fe1ad880c1e9e819725bb7a9074c 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.137 2002/12/06 05:00:31 momjian Exp $
+ * $Id: pg_type.h,v 1.138 2003/01/08 21:40:39 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,
@@ -558,21 +560,20 @@ extern Oid TypeCreate(const char *typeName,
           int32 typNDims,
           bool typeNotNull);
 
-extern void
-GenerateTypeDependencies(Oid typeNamespace,
-                        Oid typeObjectId,
-                        Oid relationOid,       /* only for 'c'atalog typeType */
-                        char relationKind,
-                        Oid inputProcedure,
-                        Oid outputProcedure,
-                        Oid elementType,
-                        Oid baseType,
-                        char *defaultTypeBin,  /* cooked rep */
-                        bool rebuild);
-
+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 */