@@ -4252,6 +4252,55 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
42524252free(qsubname);
42534253}
42544254
4255+ /*
4256+ * Given a "create query", append as many ALTER ... DEPENDS ON EXTENSION as
4257+ * the object needs.
4258+ */
4259+ static void
4260+ append_depends_on_extension(Archive *fout,
4261+ PQExpBuffer create,
4262+ DumpableObject *dobj,
4263+ const char *catalog,
4264+ const char *keyword,
4265+ const char *objname)
4266+ {
4267+ if (dobj->depends_on_ext)
4268+ {
4269+ char *nm;
4270+ PGresult *res;
4271+ PQExpBufferquery;
4272+ intntups;
4273+ inti_extname;
4274+ inti;
4275+
4276+ /* dodge fmtId() non-reentrancy */
4277+ nm = pg_strdup(objname);
4278+
4279+ query = createPQExpBuffer();
4280+ appendPQExpBuffer(query,
4281+ "SELECT e.extname "
4282+ "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
4283+ "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
4284+ "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
4285+ "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
4286+ catalog,
4287+ dobj->catId.oid);
4288+ res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4289+ ntups = PQntuples(res);
4290+ i_extname = PQfnumber(res, "extname");
4291+ for (i = 0; i < ntups; i++)
4292+ {
4293+ appendPQExpBuffer(create, "ALTER %s %s DEPENDS ON EXTENSION %s;\n",
4294+ keyword, nm,
4295+ fmtId(PQgetvalue(res, i, i_extname)));
4296+ }
4297+
4298+ PQclear(res);
4299+ pg_free(nm);
4300+ }
4301+ }
4302+
4303+
42554304static void
42564305binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
42574306 PQExpBuffer upgrade_buffer,
@@ -12070,6 +12119,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
1207012119
1207112120appendPQExpBuffer(q, "\n %s;\n", asPart->data);
1207212121
12122+ append_depends_on_extension(fout, q, &finfo->dobj,
12123+ "pg_catalog.pg_proc", keyword,
12124+ psprintf("%s.%s",
12125+ fmtId(finfo->dobj.namespace->dobj.name),
12126+ funcsig));
12127+
1207312128if (dopt->binary_upgrade)
1207412129binary_upgrade_extension_member(q, &finfo->dobj,
1207512130keyword, funcsig,
@@ -15780,6 +15835,14 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1578015835else
1578115836appendPQExpBufferStr(q, ";\n");
1578215837
15838+ /* Materialized views can depend on extensions */
15839+ if (tbinfo->relkind == RELKIND_MATVIEW)
15840+ append_depends_on_extension(fout, q, &tbinfo->dobj,
15841+ "pg_catalog.pg_class",
15842+ tbinfo->relkind == RELKIND_MATVIEW ?
15843+ "MATERIALIZED VIEW" : "INDEX",
15844+ qualrelname);
15845+
1578315846/*
1578415847 * in binary upgrade mode, update the catalog with any missing values
1578515848 * that might be present.
@@ -16280,6 +16343,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
1628016343PQExpBuffer q;
1628116344PQExpBuffer delq;
1628216345char *qindxname;
16346+ char *qqindxname;
1628316347
1628416348if (dopt->dataOnly)
1628516349return;
@@ -16288,6 +16352,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
1628816352delq = createPQExpBuffer();
1628916353
1629016354qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
16355+ qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
1629116356
1629216357/*
1629316358 * If there's an associated constraint, don't dump the index per se, but
@@ -16340,8 +16405,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
1634016405
1634116406for (j = 0; j < nstatcols; j++)
1634216407{
16343- appendPQExpBuffer(q, "ALTER INDEX %s ",
16344- fmtQualifiedDumpable(indxinfo));
16408+ appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
1634516409
1634616410/*
1634716411 * Note that this is a column number, so no quotes should be
@@ -16354,6 +16418,11 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
1635416418}
1635516419}
1635616420
16421+ /* Indexes can depend on extensions */
16422+ append_depends_on_extension(fout, q, &indxinfo->dobj,
16423+ "pg_catalog.pg_class",
16424+ "INDEX", qqindxname);
16425+
1635716426/* If the index defines identity, we need to record that. */
1635816427if (indxinfo->indisreplident)
1635916428{
@@ -16364,8 +16433,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
1636416433 qindxname);
1636516434}
1636616435
16367- appendPQExpBuffer(delq, "DROP INDEX %s;\n",
16368- fmtQualifiedDumpable(indxinfo));
16436+ appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
1636916437
1637016438if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
1637116439ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
@@ -16396,6 +16464,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
1639616464destroyPQExpBuffer(q);
1639716465destroyPQExpBuffer(delq);
1639816466free(qindxname);
16467+ free(qqindxname);
1639916468}
1640016469
1640116470/*
@@ -16625,6 +16694,11 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
1662516694 fmtId(indxinfo->dobj.name));
1662616695}
1662716696
16697+ /* Indexes can depend on extensions */
16698+ append_depends_on_extension(fout, q, &indxinfo->dobj,
16699+ "pg_catalog.pg_class", "INDEX",
16700+ fmtQualifiedDumpable(indxinfo));
16701+
1662816702appendPQExpBuffer(delq, "ALTER TABLE ONLY %s ",
1662916703 fmtQualifiedDumpable(tbinfo));
1663016704appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
@@ -17148,6 +17222,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
1714817222PQExpBuffer query;
1714917223PQExpBuffer delqry;
1715017224PQExpBuffer trigprefix;
17225+ PQExpBuffer trigidentity;
1715117226char *qtabname;
1715217227char *tgargs;
1715317228size_tlentgargs;
@@ -17165,13 +17240,14 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
1716517240query = createPQExpBuffer();
1716617241delqry = createPQExpBuffer();
1716717242trigprefix = createPQExpBuffer();
17243+ trigidentity = createPQExpBuffer();
1716817244
1716917245qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
1717017246
17171- appendPQExpBuffer(delqry , "DROP TRIGGER %s ",
17172- fmtId(tginfo->dobj.name ));
17173- appendPQExpBuffer(delqry, "ON %s;\n",
17174- fmtQualifiedDumpable(tbinfo) );
17247+ appendPQExpBuffer(trigidentity , "%s ", fmtId(tginfo->dobj.name));
17248+ appendPQExpBuffer(trigidentity, "ON %s", fmtQualifiedDumpable(tbinfo ));
17249+
17250+ appendPQExpBuffer(delqry, "DROP TRIGGER %s;\n", trigidentity->data );
1717517251
1717617252if (tginfo->tgdef)
1717717253{
@@ -17290,6 +17366,11 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
1729017366appendPQExpBufferStr(query, ");\n");
1729117367}
1729217368
17369+ /* Triggers can depend on extensions */
17370+ append_depends_on_extension(fout, query, &tginfo->dobj,
17371+ "pg_catalog.pg_trigger", "TRIGGER",
17372+ trigidentity->data);
17373+
1729317374if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
1729417375{
1729517376appendPQExpBuffer(query, "\nALTER TABLE %s ",
@@ -17339,6 +17420,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
1733917420destroyPQExpBuffer(query);
1734017421destroyPQExpBuffer(delqry);
1734117422destroyPQExpBuffer(trigprefix);
17423+ destroyPQExpBuffer(trigidentity);
1734217424free(qtabname);
1734317425}
1734417426
@@ -17995,6 +18077,15 @@ getDependencies(Archive *fout)
1799518077continue;
1799618078}
1799718079
18080+ /*
18081+ * For 'x' dependencies, mark the object for later; we still add the
18082+ * normal dependency, for possible ordering purposes. Currently
18083+ * pg_dump_sort.c knows to put extensions ahead of all object types
18084+ * that could possibly depend on them, but this is safer.
18085+ */
18086+ if (deptype == 'x')
18087+ dobj->depends_on_ext = true;
18088+
1799818089/*
1799918090 * Ordinarily, table rowtypes have implicit dependencies on their
1800018091 * tables. However, for a composite type the implicit dependency goes