]> granicus.if.org Git - postgresql/commitdiff
Fix pg_dump to dump shell types.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 4 Aug 2015 23:34:12 +0000 (19:34 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 4 Aug 2015 23:34:12 +0000 (19:34 -0400)
Per discussion, it really ought to do this.  The original choice to
exclude shell types was probably made in the dark ages before we made
it harder to accidentally create shell types; but that was in 7.3.

Also, cause the standard regression tests to leave a shell type behind,
for convenience in testing the case in pg_dump and pg_upgrade.

Back-patch to all supported branches.

src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h
src/test/regress/expected/create_type.out
src/test/regress/sql/create_type.sql

index 7e50e727284a55e58d9cb76408e4063e43d14c35..e37a61a5abcf568d4c8f624b0caa4b30ea9ca6d9 100644 (file)
@@ -143,6 +143,7 @@ static void dumpNamespace(Archive *fout, NamespaceInfo *nspinfo);
 static void dumpType(Archive *fout, TypeInfo *tyinfo);
 static void dumpBaseType(Archive *fout, TypeInfo *tyinfo);
 static void dumpEnumType(Archive *fout, TypeInfo *tyinfo);
+static void dumpUndefinedType(Archive *fout, TypeInfo *tyinfo);
 static void dumpDomain(Archive *fout, TypeInfo *tyinfo);
 static void dumpCompositeType(Archive *fout, TypeInfo *tyinfo);
 static void dumpCompositeTypeColComments(Archive *fout, TypeInfo *tyinfo);
@@ -1056,11 +1057,6 @@ selectDumpableType(TypeInfo *tyinfo)
        /* dump only types in dumpable namespaces */
        if (!tyinfo->dobj.namespace->dobj.dump)
                tyinfo->dobj.dump = false;
-
-       /* skip undefined placeholder types */
-       else if (!tyinfo->isDefined)
-               tyinfo->dobj.dump = false;
-
        else
                tyinfo->dobj.dump = true;
 }
@@ -2760,7 +2756,7 @@ getTypes(int *numTypes)
                        }
                }
 
-               if (strlen(tyinfo[i].rolname) == 0 && tyinfo[i].isDefined)
+               if (strlen(tyinfo[i].rolname) == 0)
                        write_msg(NULL, "WARNING: owner of data type \"%s\" appears to be invalid\n",
                                          tyinfo[i].dobj.name);
        }
@@ -6711,6 +6707,11 @@ dumpType(Archive *fout, TypeInfo *tyinfo)
                dumpCompositeType(fout, tyinfo);
        else if (tyinfo->typtype == TYPTYPE_ENUM)
                dumpEnumType(fout, tyinfo);
+       else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
+               dumpUndefinedType(fout, tyinfo);
+       else
+               write_msg(NULL, "WARNING: typtype of data type \"%s\" appears to be invalid\n",
+                                 tyinfo->dobj.name);
 }
 
 /*
@@ -6818,6 +6819,61 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
        destroyPQExpBuffer(query);
 }
 
+/*
+ * dumpUndefinedType
+ *       writes out to fout the queries to recreate a !typisdefined type
+ *
+ * This is a shell type, but we use different terminology to distinguish
+ * this case from where we have to emit a shell type definition to break
+ * circular dependencies.  An undefined type shouldn't ever have anything
+ * depending on it.
+ */
+static void
+dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
+{
+       PQExpBuffer q = createPQExpBuffer();
+       PQExpBuffer delq = createPQExpBuffer();
+       PQExpBuffer labelq = createPQExpBuffer();
+       char       *qtypname;
+
+       qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
+
+       /*
+        * DROP must be fully qualified in case same name appears in pg_catalog.
+        */
+       appendPQExpBuffer(delq, "DROP TYPE %s.",
+                                         fmtId(tyinfo->dobj.namespace->dobj.name));
+       appendPQExpBuffer(delq, "%s;\n",
+                                         qtypname);
+
+       if (binary_upgrade)
+               binary_upgrade_set_type_oids_by_type_oid(q, tyinfo->dobj.catId.oid);
+
+       appendPQExpBuffer(q, "CREATE TYPE %s;\n",
+                                         qtypname);
+
+       appendPQExpBuffer(labelq, "TYPE %s", qtypname);
+
+       ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
+                                tyinfo->dobj.name,
+                                tyinfo->dobj.namespace->dobj.name,
+                                NULL,
+                                tyinfo->rolname, false,
+                                "TYPE", SECTION_PRE_DATA,
+                                q->data, delq->data, NULL,
+                                NULL, 0,
+                                NULL, NULL);
+
+       /* Dump Type Comments */
+       dumpComment(fout, labelq->data,
+                               tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
+                               tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
+
+       destroyPQExpBuffer(q);
+       destroyPQExpBuffer(delq);
+       destroyPQExpBuffer(labelq);
+}
+
 /*
  * dumpBaseType
  *       writes out to fout the queries to recreate a user-defined base type
index cf5092c3a106dc1868efeeabb1109d5e7cde601b..ae6ae76db3b7aada11c20ee1c97817ab2736e588 100644 (file)
@@ -154,7 +154,7 @@ typedef struct _typeInfo
        char            typtype;                /* 'b', 'c', etc */
        bool            isArray;                /* true if auto-generated array type */
        bool            isDefined;              /* true if typisdefined */
-       /* If it's a dumpable base type, we create a "shell type" entry for it */
+       /* If needed, we'll create a "shell type" entry for it; link that here: */
        struct _shellTypeInfo *shellType;       /* shell-type entry, or NULL */
        /* If it's a domain, we store links to its constraints here: */
        int                     nDomChecks;
index 1d3a22612d31d1d0de684cf92b3401906f1fa742..7f5486fad7da6888d640671479faa63db08a3886 100644 (file)
@@ -29,6 +29,8 @@ ERROR:  type "shell" already exists
 DROP TYPE shell;
 DROP TYPE shell;     -- fail, type not exist
 ERROR:  type "shell" does not exist
+-- also, let's leave one around for purposes of pg_dump testing
+CREATE TYPE myshell;
 --
 -- Test type-related default values (broken in releases before PG 7.2)
 --
index b9cd7af1ab8755d4187921b09950e4a8f4521db5..8a18ed67525bac01d7b06c1a0583c8e1cb35167e 100644 (file)
@@ -31,6 +31,9 @@ CREATE TYPE shell;   -- fail, type already present
 DROP TYPE shell;
 DROP TYPE shell;     -- fail, type not exist
 
+-- also, let's leave one around for purposes of pg_dump testing
+CREATE TYPE myshell;
+
 --
 -- Test type-related default values (broken in releases before PG 7.2)
 --