@@ -4252,6 +4252,55 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
4252
4252
free(qsubname);
4253
4253
}
4254
4254
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
+
4255
4304
static void
4256
4305
binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
4257
4306
PQExpBuffer upgrade_buffer,
@@ -12070,6 +12119,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
12070
12119
12071
12120
appendPQExpBuffer(q, "\n %s;\n", asPart->data);
12072
12121
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
+
12073
12128
if (dopt->binary_upgrade)
12074
12129
binary_upgrade_extension_member(q, &finfo->dobj,
12075
12130
keyword, funcsig,
@@ -15780,6 +15835,14 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15780
15835
else
15781
15836
appendPQExpBufferStr(q, ";\n");
15782
15837
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
+
15783
15846
/*
15784
15847
* in binary upgrade mode, update the catalog with any missing values
15785
15848
* that might be present.
@@ -16280,6 +16343,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16280
16343
PQExpBuffer q;
16281
16344
PQExpBuffer delq;
16282
16345
char *qindxname;
16346
+ char *qqindxname;
16283
16347
16284
16348
if (dopt->dataOnly)
16285
16349
return;
@@ -16288,6 +16352,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16288
16352
delq = createPQExpBuffer();
16289
16353
16290
16354
qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
16355
+ qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
16291
16356
16292
16357
/*
16293
16358
* If there's an associated constraint, don't dump the index per se, but
@@ -16340,8 +16405,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16340
16405
16341
16406
for (j = 0; j < nstatcols; j++)
16342
16407
{
16343
- appendPQExpBuffer(q, "ALTER INDEX %s ",
16344
- fmtQualifiedDumpable(indxinfo));
16408
+ appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
16345
16409
16346
16410
/*
16347
16411
* Note that this is a column number, so no quotes should be
@@ -16354,6 +16418,11 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16354
16418
}
16355
16419
}
16356
16420
16421
+ /* Indexes can depend on extensions */
16422
+ append_depends_on_extension(fout, q, &indxinfo->dobj,
16423
+ "pg_catalog.pg_class",
16424
+ "INDEX", qqindxname);
16425
+
16357
16426
/* If the index defines identity, we need to record that. */
16358
16427
if (indxinfo->indisreplident)
16359
16428
{
@@ -16364,8 +16433,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16364
16433
qindxname);
16365
16434
}
16366
16435
16367
- appendPQExpBuffer(delq, "DROP INDEX %s;\n",
16368
- fmtQualifiedDumpable(indxinfo));
16436
+ appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
16369
16437
16370
16438
if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16371
16439
ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
@@ -16396,6 +16464,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16396
16464
destroyPQExpBuffer(q);
16397
16465
destroyPQExpBuffer(delq);
16398
16466
free(qindxname);
16467
+ free(qqindxname);
16399
16468
}
16400
16469
16401
16470
/*
@@ -16625,6 +16694,11 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
16625
16694
fmtId(indxinfo->dobj.name));
16626
16695
}
16627
16696
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
+
16628
16702
appendPQExpBuffer(delq, "ALTER TABLE ONLY %s ",
16629
16703
fmtQualifiedDumpable(tbinfo));
16630
16704
appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
@@ -17148,6 +17222,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17148
17222
PQExpBuffer query;
17149
17223
PQExpBuffer delqry;
17150
17224
PQExpBuffer trigprefix;
17225
+ PQExpBuffer trigidentity;
17151
17226
char *qtabname;
17152
17227
char *tgargs;
17153
17228
size_tlentgargs;
@@ -17165,13 +17240,14 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17165
17240
query = createPQExpBuffer();
17166
17241
delqry = createPQExpBuffer();
17167
17242
trigprefix = createPQExpBuffer();
17243
+ trigidentity = createPQExpBuffer();
17168
17244
17169
17245
qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
17170
17246
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 );
17175
17251
17176
17252
if (tginfo->tgdef)
17177
17253
{
@@ -17290,6 +17366,11 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17290
17366
appendPQExpBufferStr(query, ");\n");
17291
17367
}
17292
17368
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
+
17293
17374
if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17294
17375
{
17295
17376
appendPQExpBuffer(query, "\nALTER TABLE %s ",
@@ -17339,6 +17420,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17339
17420
destroyPQExpBuffer(query);
17340
17421
destroyPQExpBuffer(delqry);
17341
17422
destroyPQExpBuffer(trigprefix);
17423
+ destroyPQExpBuffer(trigidentity);
17342
17424
free(qtabname);
17343
17425
}
17344
17426
@@ -17995,6 +18077,15 @@ getDependencies(Archive *fout)
17995
18077
continue;
17996
18078
}
17997
18079
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
+
17998
18089
/*
17999
18090
* Ordinarily, table rowtypes have implicit dependencies on their
18000
18091
* tables. However, for a composite type the implicit dependency goes