aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/pg_dump.c74
-rw-r--r--src/bin/pg_dump/pg_dump.h2
-rw-r--r--src/test/regress/expected/create_type.out2
-rw-r--r--src/test/regress/sql/create_type.sql3
4 files changed, 74 insertions, 7 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 710b779c7ee..a7d106d44b2 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -163,6 +163,7 @@ static void dumpExtension(Archive *fout, ExtensionInfo *extinfo);
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);
@@ -1184,11 +1185,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;
}
@@ -3118,7 +3114,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);
}
@@ -7408,6 +7404,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);
}
/*
@@ -7532,6 +7533,67 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
}
/*
+ * 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);
+
+ if (binary_upgrade)
+ binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
+
+ 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 and Security Labels */
+ dumpComment(fout, labelq->data,
+ tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
+ tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
+ dumpSecLabel(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
*/
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 828b6cf3225..90296ca7384 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -169,7 +169,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;
diff --git a/src/test/regress/expected/create_type.out b/src/test/regress/expected/create_type.out
index 6dfe9169854..09459adc3fe 100644
--- a/src/test/regress/expected/create_type.out
+++ b/src/test/regress/expected/create_type.out
@@ -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)
--
diff --git a/src/test/regress/sql/create_type.sql b/src/test/regress/sql/create_type.sql
index a4906b64e10..62bd53cfbae 100644
--- a/src/test/regress/sql/create_type.sql
+++ b/src/test/regress/sql/create_type.sql
@@ -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)
--