@@ -4285,6 +4285,55 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
42854285free(qsubname);
42864286}
42874287
4288+ /*
4289+ * Given a "create query", append as many ALTER ... DEPENDS ON EXTENSION as
4290+ * the object needs.
4291+ */
4292+ static void
4293+ append_depends_on_extension(Archive *fout,
4294+ PQExpBuffer create,
4295+ DumpableObject *dobj,
4296+ const char *catalog,
4297+ const char *keyword,
4298+ const char *objname)
4299+ {
4300+ if (dobj->depends_on_ext)
4301+ {
4302+ char *nm;
4303+ PGresult *res;
4304+ PQExpBufferquery;
4305+ intntups;
4306+ inti_extname;
4307+ inti;
4308+
4309+ /* dodge fmtId() non-reentrancy */
4310+ nm = pg_strdup(objname);
4311+
4312+ query = createPQExpBuffer();
4313+ appendPQExpBuffer(query,
4314+ "SELECT e.extname "
4315+ "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
4316+ "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
4317+ "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
4318+ "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
4319+ catalog,
4320+ dobj->catId.oid);
4321+ res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4322+ ntups = PQntuples(res);
4323+ i_extname = PQfnumber(res, "extname");
4324+ for (i = 0; i < ntups; i++)
4325+ {
4326+ appendPQExpBuffer(create, "ALTER %s %s DEPENDS ON EXTENSION %s;\n",
4327+ keyword, nm,
4328+ fmtId(PQgetvalue(res, i, i_extname)));
4329+ }
4330+
4331+ PQclear(res);
4332+ pg_free(nm);
4333+ }
4334+ }
4335+
4336+
42884337static void
42894338binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
42904339 PQExpBuffer upgrade_buffer,
@@ -12148,6 +12197,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
1214812197
1214912198appendPQExpBuffer(q, "\n %s;\n", asPart->data);
1215012199
12200+ append_depends_on_extension(fout, q, &finfo->dobj,
12201+ "pg_catalog.pg_proc", keyword,
12202+ psprintf("%s.%s",
12203+ fmtId(finfo->dobj.namespace->dobj.name),
12204+ funcsig));
12205+
1215112206if (dopt->binary_upgrade)
1215212207binary_upgrade_extension_member(q, &finfo->dobj,
1215312208keyword, funcsig,
@@ -15860,6 +15915,14 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
1586015915else
1586115916appendPQExpBufferStr(q, ";\n");
1586215917
15918+ /* Materialized views can depend on extensions */
15919+ if (tbinfo->relkind == RELKIND_MATVIEW)
15920+ append_depends_on_extension(fout, q, &tbinfo->dobj,
15921+ "pg_catalog.pg_class",
15922+ tbinfo->relkind == RELKIND_MATVIEW ?
15923+ "MATERIALIZED VIEW" : "INDEX",
15924+ qualrelname);
15925+
1586315926/*
1586415927 * in binary upgrade mode, update the catalog with any missing values
1586515928 * that might be present.
@@ -16364,6 +16427,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
1636416427PQExpBuffer q;
1636516428PQExpBuffer delq;
1636616429char *qindxname;
16430+ char *qqindxname;
1636716431
1636816432if (dopt->dataOnly)
1636916433return;
@@ -16372,6 +16436,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
1637216436delq = createPQExpBuffer();
1637316437
1637416438qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
16439+ qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
1637516440
1637616441/*
1637716442 * If there's an associated constraint, don't dump the index per se, but
@@ -16424,8 +16489,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
1642416489
1642516490for (j = 0; j < nstatcols; j++)
1642616491{
16427- appendPQExpBuffer(q, "ALTER INDEX %s ",
16428- fmtQualifiedDumpable(indxinfo));
16492+ appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
1642916493
1643016494/*
1643116495 * Note that this is a column number, so no quotes should be
@@ -16438,6 +16502,11 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
1643816502}
1643916503}
1644016504
16505+ /* Indexes can depend on extensions */
16506+ append_depends_on_extension(fout, q, &indxinfo->dobj,
16507+ "pg_catalog.pg_class",
16508+ "INDEX", qqindxname);
16509+
1644116510/* If the index defines identity, we need to record that. */
1644216511if (indxinfo->indisreplident)
1644316512{
@@ -16448,8 +16517,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
1644816517 qindxname);
1644916518}
1645016519
16451- appendPQExpBuffer(delq, "DROP INDEX %s;\n",
16452- fmtQualifiedDumpable(indxinfo));
16520+ appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
1645316521
1645416522if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
1645516523ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
@@ -16480,6 +16548,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
1648016548destroyPQExpBuffer(q);
1648116549destroyPQExpBuffer(delq);
1648216550free(qindxname);
16551+ free(qqindxname);
1648316552}
1648416553
1648516554/*
@@ -16705,6 +16774,11 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
1670516774 fmtId(indxinfo->dobj.name));
1670616775}
1670716776
16777+ /* Indexes can depend on extensions */
16778+ append_depends_on_extension(fout, q, &indxinfo->dobj,
16779+ "pg_catalog.pg_class", "INDEX",
16780+ fmtQualifiedDumpable(indxinfo));
16781+
1670816782appendPQExpBuffer(delq, "ALTER TABLE ONLY %s ",
1670916783 fmtQualifiedDumpable(tbinfo));
1671016784appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
@@ -17224,6 +17298,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
1722417298PQExpBuffer query;
1722517299PQExpBuffer delqry;
1722617300PQExpBuffer trigprefix;
17301+ PQExpBuffer trigidentity;
1722717302char *qtabname;
1722817303char *tgargs;
1722917304size_tlentgargs;
@@ -17241,13 +17316,14 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
1724117316query = createPQExpBuffer();
1724217317delqry = createPQExpBuffer();
1724317318trigprefix = createPQExpBuffer();
17319+ trigidentity = createPQExpBuffer();
1724417320
1724517321qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
1724617322
17247- appendPQExpBuffer(delqry , "DROP TRIGGER %s ",
17248- fmtId(tginfo->dobj.name ));
17249- appendPQExpBuffer(delqry, "ON %s;\n",
17250- fmtQualifiedDumpable(tbinfo) );
17323+ appendPQExpBuffer(trigidentity , "%s ", fmtId(tginfo->dobj.name));
17324+ appendPQExpBuffer(trigidentity, "ON %s", fmtQualifiedDumpable(tbinfo ));
17325+
17326+ appendPQExpBuffer(delqry, "DROP TRIGGER %s;\n", trigidentity->data );
1725117327
1725217328if (tginfo->tgdef)
1725317329{
@@ -17366,6 +17442,11 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
1736617442appendPQExpBufferStr(query, ");\n");
1736717443}
1736817444
17445+ /* Triggers can depend on extensions */
17446+ append_depends_on_extension(fout, query, &tginfo->dobj,
17447+ "pg_catalog.pg_trigger", "TRIGGER",
17448+ trigidentity->data);
17449+
1736917450if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
1737017451{
1737117452appendPQExpBuffer(query, "\nALTER TABLE %s ",
@@ -17414,6 +17495,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
1741417495destroyPQExpBuffer(query);
1741517496destroyPQExpBuffer(delqry);
1741617497destroyPQExpBuffer(trigprefix);
17498+ destroyPQExpBuffer(trigidentity);
1741717499free(qtabname);
1741817500}
1741917501
@@ -18063,6 +18145,15 @@ getDependencies(Archive *fout)
1806318145continue;
1806418146}
1806518147
18148+ /*
18149+ * For 'x' dependencies, mark the object for later; we still add the
18150+ * normal dependency, for possible ordering purposes. Currently
18151+ * pg_dump_sort.c knows to put extensions ahead of all object types
18152+ * that could possibly depend on them, but this is safer.
18153+ */
18154+ if (deptype == 'x')
18155+ dobj->depends_on_ext = true;
18156+
1806618157/*
1806718158 * Ordinarily, table rowtypes have implicit dependencies on their
1806818159 * tables. However, for a composite type the implicit dependency goes