aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/pg_dump.c77
-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, 77 insertions, 7 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 00b86766336..51b6d3ae77e 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -158,6 +158,7 @@ static void dumpType(Archive *fout, DumpOptions *dopt, TypeInfo *tyinfo);
static void dumpBaseType(Archive *fout, DumpOptions *dopt, TypeInfo *tyinfo);
static void dumpEnumType(Archive *fout, DumpOptions *dopt, TypeInfo *tyinfo);
static void dumpRangeType(Archive *fout, DumpOptions *dopt, TypeInfo *tyinfo);
+static void dumpUndefinedType(Archive *fout, DumpOptions *dopt, TypeInfo *tyinfo);
static void dumpDomain(Archive *fout, DumpOptions *dopt, TypeInfo *tyinfo);
static void dumpCompositeType(Archive *fout, DumpOptions *dopt, TypeInfo *tyinfo);
static void dumpCompositeTypeColComments(Archive *fout, TypeInfo *tyinfo);
@@ -1329,11 +1330,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;
}
@@ -3707,7 +3703,7 @@ getTypes(Archive *fout, 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);
}
@@ -8554,6 +8550,8 @@ dumpType(Archive *fout, DumpOptions *dopt, TypeInfo *tyinfo)
dumpEnumType(fout, dopt, tyinfo);
else if (tyinfo->typtype == TYPTYPE_RANGE)
dumpRangeType(fout, dopt, tyinfo);
+ else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
+ dumpUndefinedType(fout, dopt, tyinfo);
else
write_msg(NULL, "WARNING: typtype of data type \"%s\" appears to be invalid\n",
tyinfo->dobj.name);
@@ -8821,6 +8819,73 @@ dumpRangeType(Archive *fout, DumpOptions *dopt, 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, DumpOptions *dopt, 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 (dopt->binary_upgrade)
+ binary_upgrade_set_type_oids_by_type_oid(fout,
+ q, tyinfo->dobj.catId.oid);
+
+ appendPQExpBuffer(q, "CREATE TYPE %s;\n",
+ qtypname);
+
+ appendPQExpBuffer(labelq, "TYPE %s", qtypname);
+
+ if (dopt->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, dopt, labelq->data,
+ tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
+ tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
+ dumpSecLabel(fout, dopt, labelq->data,
+ tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
+ tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
+
+ dumpACL(fout, dopt, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
+ qtypname, NULL, tyinfo->dobj.name,
+ tyinfo->dobj.namespace->dobj.name,
+ tyinfo->rolname, tyinfo->typacl);
+
+ 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 009dba5c9d7..da7597ded1c 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -127,7 +127,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 b5af862ce5c..7bdad4e9bb5 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 29ba625b46a..a1839ef9e7f 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)
--