diff options
Diffstat (limited to 'src/bin/pg_dump/pg_dump.c')
-rw-r--r-- | src/bin/pg_dump/pg_dump.c | 107 |
1 files changed, 99 insertions, 8 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 79a5aa8957e..4185c97fdb1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -4252,6 +4252,55 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo) free(qsubname); } +/* + * Given a "create query", append as many ALTER ... DEPENDS ON EXTENSION as + * the object needs. + */ +static void +append_depends_on_extension(Archive *fout, + PQExpBuffer create, + DumpableObject *dobj, + const char *catalog, + const char *keyword, + const char *objname) +{ + if (dobj->depends_on_ext) + { + char *nm; + PGresult *res; + PQExpBuffer query; + int ntups; + int i_extname; + int i; + + /* dodge fmtId() non-reentrancy */ + nm = pg_strdup(objname); + + query = createPQExpBuffer(); + appendPQExpBuffer(query, + "SELECT e.extname " + "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e " + "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass " + "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' " + "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass", + catalog, + dobj->catId.oid); + res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); + ntups = PQntuples(res); + i_extname = PQfnumber(res, "extname"); + for (i = 0; i < ntups; i++) + { + appendPQExpBuffer(create, "ALTER %s %s DEPENDS ON EXTENSION %s;\n", + keyword, nm, + fmtId(PQgetvalue(res, i, i_extname))); + } + + PQclear(res); + pg_free(nm); + } +} + + static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout, PQExpBuffer upgrade_buffer, @@ -12070,6 +12119,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo) appendPQExpBuffer(q, "\n %s;\n", asPart->data); + append_depends_on_extension(fout, q, &finfo->dobj, + "pg_catalog.pg_proc", keyword, + psprintf("%s.%s", + fmtId(finfo->dobj.namespace->dobj.name), + funcsig)); + if (dopt->binary_upgrade) binary_upgrade_extension_member(q, &finfo->dobj, keyword, funcsig, @@ -15780,6 +15835,14 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) else appendPQExpBufferStr(q, ";\n"); + /* Materialized views can depend on extensions */ + if (tbinfo->relkind == RELKIND_MATVIEW) + append_depends_on_extension(fout, q, &tbinfo->dobj, + "pg_catalog.pg_class", + tbinfo->relkind == RELKIND_MATVIEW ? + "MATERIALIZED VIEW" : "INDEX", + qualrelname); + /* * in binary upgrade mode, update the catalog with any missing values * that might be present. @@ -16280,6 +16343,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo) PQExpBuffer q; PQExpBuffer delq; char *qindxname; + char *qqindxname; if (dopt->dataOnly) return; @@ -16288,6 +16352,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo) delq = createPQExpBuffer(); qindxname = pg_strdup(fmtId(indxinfo->dobj.name)); + qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo)); /* * If there's an associated constraint, don't dump the index per se, but @@ -16340,8 +16405,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo) for (j = 0; j < nstatcols; j++) { - appendPQExpBuffer(q, "ALTER INDEX %s ", - fmtQualifiedDumpable(indxinfo)); + appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname); /* * Note that this is a column number, so no quotes should be @@ -16354,6 +16418,11 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo) } } + /* Indexes can depend on extensions */ + append_depends_on_extension(fout, q, &indxinfo->dobj, + "pg_catalog.pg_class", + "INDEX", qqindxname); + /* If the index defines identity, we need to record that. */ if (indxinfo->indisreplident) { @@ -16364,8 +16433,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo) qindxname); } - appendPQExpBuffer(delq, "DROP INDEX %s;\n", - fmtQualifiedDumpable(indxinfo)); + appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname); if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId, @@ -16396,6 +16464,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo) destroyPQExpBuffer(q); destroyPQExpBuffer(delq); free(qindxname); + free(qqindxname); } /* @@ -16625,6 +16694,11 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) fmtId(indxinfo->dobj.name)); } + /* Indexes can depend on extensions */ + append_depends_on_extension(fout, q, &indxinfo->dobj, + "pg_catalog.pg_class", "INDEX", + fmtQualifiedDumpable(indxinfo)); + appendPQExpBuffer(delq, "ALTER TABLE ONLY %s ", fmtQualifiedDumpable(tbinfo)); appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n", @@ -17148,6 +17222,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) PQExpBuffer query; PQExpBuffer delqry; PQExpBuffer trigprefix; + PQExpBuffer trigidentity; char *qtabname; char *tgargs; size_t lentgargs; @@ -17165,13 +17240,14 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) query = createPQExpBuffer(); delqry = createPQExpBuffer(); trigprefix = createPQExpBuffer(); + trigidentity = createPQExpBuffer(); qtabname = pg_strdup(fmtId(tbinfo->dobj.name)); - appendPQExpBuffer(delqry, "DROP TRIGGER %s ", - fmtId(tginfo->dobj.name)); - appendPQExpBuffer(delqry, "ON %s;\n", - fmtQualifiedDumpable(tbinfo)); + appendPQExpBuffer(trigidentity, "%s ", fmtId(tginfo->dobj.name)); + appendPQExpBuffer(trigidentity, "ON %s", fmtQualifiedDumpable(tbinfo)); + + appendPQExpBuffer(delqry, "DROP TRIGGER %s;\n", trigidentity->data); if (tginfo->tgdef) { @@ -17290,6 +17366,11 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) appendPQExpBufferStr(query, ");\n"); } + /* Triggers can depend on extensions */ + append_depends_on_extension(fout, query, &tginfo->dobj, + "pg_catalog.pg_trigger", "TRIGGER", + trigidentity->data); + if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O') { appendPQExpBuffer(query, "\nALTER TABLE %s ", @@ -17339,6 +17420,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) destroyPQExpBuffer(query); destroyPQExpBuffer(delqry); destroyPQExpBuffer(trigprefix); + destroyPQExpBuffer(trigidentity); free(qtabname); } @@ -17996,6 +18078,15 @@ getDependencies(Archive *fout) } /* + * For 'x' dependencies, mark the object for later; we still add the + * normal dependency, for possible ordering purposes. Currently + * pg_dump_sort.c knows to put extensions ahead of all object types + * that could possibly depend on them, but this is safer. + */ + if (deptype == 'x') + dobj->depends_on_ext = true; + + /* * Ordinarily, table rowtypes have implicit dependencies on their * tables. However, for a composite type the implicit dependency goes * the other way in pg_depend; which is the right thing for DROP but |