@@ -4285,6 +4285,55 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
4285
4285
free(qsubname);
4286
4286
}
4287
4287
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
+ PQExpBuffer query;
4305
+ int ntups;
4306
+ int i_extname;
4307
+ int i;
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
+
4288
4337
static void
4289
4338
binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
4290
4339
PQExpBuffer upgrade_buffer,
@@ -12148,6 +12197,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
12148
12197
12149
12198
appendPQExpBuffer(q, "\n %s;\n", asPart->data);
12150
12199
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
+
12151
12206
if (dopt->binary_upgrade)
12152
12207
binary_upgrade_extension_member(q, &finfo->dobj,
12153
12208
keyword, funcsig,
@@ -15860,6 +15915,14 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15860
15915
else
15861
15916
appendPQExpBufferStr(q, ";\n");
15862
15917
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
+
15863
15926
/*
15864
15927
* in binary upgrade mode, update the catalog with any missing values
15865
15928
* that might be present.
@@ -16364,6 +16427,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16364
16427
PQExpBuffer q;
16365
16428
PQExpBuffer delq;
16366
16429
char *qindxname;
16430
+ char *qqindxname;
16367
16431
16368
16432
if (dopt->dataOnly)
16369
16433
return;
@@ -16372,6 +16436,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16372
16436
delq = createPQExpBuffer();
16373
16437
16374
16438
qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
16439
+ qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
16375
16440
16376
16441
/*
16377
16442
* If there's an associated constraint, don't dump the index per se, but
@@ -16424,8 +16489,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16424
16489
16425
16490
for (j = 0; j < nstatcols; j++)
16426
16491
{
16427
- appendPQExpBuffer(q, "ALTER INDEX %s ",
16428
- fmtQualifiedDumpable(indxinfo));
16492
+ appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
16429
16493
16430
16494
/*
16431
16495
* Note that this is a column number, so no quotes should be
@@ -16438,6 +16502,11 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16438
16502
}
16439
16503
}
16440
16504
16505
+ /* Indexes can depend on extensions */
16506
+ append_depends_on_extension(fout, q, &indxinfo->dobj,
16507
+ "pg_catalog.pg_class",
16508
+ "INDEX", qqindxname);
16509
+
16441
16510
/* If the index defines identity, we need to record that. */
16442
16511
if (indxinfo->indisreplident)
16443
16512
{
@@ -16448,8 +16517,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16448
16517
qindxname);
16449
16518
}
16450
16519
16451
- appendPQExpBuffer(delq, "DROP INDEX %s;\n",
16452
- fmtQualifiedDumpable(indxinfo));
16520
+ appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
16453
16521
16454
16522
if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16455
16523
ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
@@ -16480,6 +16548,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16480
16548
destroyPQExpBuffer(q);
16481
16549
destroyPQExpBuffer(delq);
16482
16550
free(qindxname);
16551
+ free(qqindxname);
16483
16552
}
16484
16553
16485
16554
/*
@@ -16705,6 +16774,11 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
16705
16774
fmtId(indxinfo->dobj.name));
16706
16775
}
16707
16776
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
+
16708
16782
appendPQExpBuffer(delq, "ALTER TABLE ONLY %s ",
16709
16783
fmtQualifiedDumpable(tbinfo));
16710
16784
appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
@@ -17224,6 +17298,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17224
17298
PQExpBuffer query;
17225
17299
PQExpBuffer delqry;
17226
17300
PQExpBuffer trigprefix;
17301
+ PQExpBuffer trigidentity;
17227
17302
char *qtabname;
17228
17303
char *tgargs;
17229
17304
size_t lentgargs;
@@ -17241,13 +17316,14 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17241
17316
query = createPQExpBuffer();
17242
17317
delqry = createPQExpBuffer();
17243
17318
trigprefix = createPQExpBuffer();
17319
+ trigidentity = createPQExpBuffer();
17244
17320
17245
17321
qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
17246
17322
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 );
17251
17327
17252
17328
if (tginfo->tgdef)
17253
17329
{
@@ -17366,6 +17442,11 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17366
17442
appendPQExpBufferStr(query, ");\n");
17367
17443
}
17368
17444
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
+
17369
17450
if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17370
17451
{
17371
17452
appendPQExpBuffer(query, "\nALTER TABLE %s ",
@@ -17414,6 +17495,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17414
17495
destroyPQExpBuffer(query);
17415
17496
destroyPQExpBuffer(delqry);
17416
17497
destroyPQExpBuffer(trigprefix);
17498
+ destroyPQExpBuffer(trigidentity);
17417
17499
free(qtabname);
17418
17500
}
17419
17501
@@ -18063,6 +18145,15 @@ getDependencies(Archive *fout)
18063
18145
continue;
18064
18146
}
18065
18147
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
+
18066
18157
/*
18067
18158
* Ordinarily, table rowtypes have implicit dependencies on their
18068
18159
* tables. However, for a composite type the implicit dependency goes
0 commit comments