@@ -4291,6 +4291,55 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
4291
4291
free(qsubname);
4292
4292
}
4293
4293
4294
+ /*
4295
+ * Given a "create query", append as many ALTER ... DEPENDS ON EXTENSION as
4296
+ * the object needs.
4297
+ */
4298
+ static void
4299
+ append_depends_on_extension(Archive *fout,
4300
+ PQExpBuffer create,
4301
+ DumpableObject *dobj,
4302
+ const char *catalog,
4303
+ const char *keyword,
4304
+ const char *objname)
4305
+ {
4306
+ if (dobj->depends_on_ext)
4307
+ {
4308
+ char *nm;
4309
+ PGresult *res;
4310
+ PQExpBuffer query;
4311
+ int ntups;
4312
+ int i_extname;
4313
+ int i;
4314
+
4315
+ /* dodge fmtId() non-reentrancy */
4316
+ nm = pg_strdup(objname);
4317
+
4318
+ query = createPQExpBuffer();
4319
+ appendPQExpBuffer(query,
4320
+ "SELECT e.extname "
4321
+ "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
4322
+ "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
4323
+ "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
4324
+ "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
4325
+ catalog,
4326
+ dobj->catId.oid);
4327
+ res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
4328
+ ntups = PQntuples(res);
4329
+ i_extname = PQfnumber(res, "extname");
4330
+ for (i = 0; i < ntups; i++)
4331
+ {
4332
+ appendPQExpBuffer(create, "ALTER %s %s DEPENDS ON EXTENSION %s;\n",
4333
+ keyword, nm,
4334
+ fmtId(PQgetvalue(res, i, i_extname)));
4335
+ }
4336
+
4337
+ PQclear(res);
4338
+ pg_free(nm);
4339
+ }
4340
+ }
4341
+
4342
+
4294
4343
static void
4295
4344
binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
4296
4345
PQExpBuffer upgrade_buffer,
@@ -12161,6 +12210,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
12161
12210
12162
12211
appendPQExpBuffer(q, "\n %s;\n", asPart->data);
12163
12212
12213
+ append_depends_on_extension(fout, q, &finfo->dobj,
12214
+ "pg_catalog.pg_proc", keyword,
12215
+ psprintf("%s.%s",
12216
+ fmtId(finfo->dobj.namespace->dobj.name),
12217
+ funcsig));
12218
+
12164
12219
if (dopt->binary_upgrade)
12165
12220
binary_upgrade_extension_member(q, &finfo->dobj,
12166
12221
keyword, funcsig,
@@ -15871,6 +15926,14 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
15871
15926
else
15872
15927
appendPQExpBufferStr(q, ";\n");
15873
15928
15929
+ /* Materialized views can depend on extensions */
15930
+ if (tbinfo->relkind == RELKIND_MATVIEW)
15931
+ append_depends_on_extension(fout, q, &tbinfo->dobj,
15932
+ "pg_catalog.pg_class",
15933
+ tbinfo->relkind == RELKIND_MATVIEW ?
15934
+ "MATERIALIZED VIEW" : "INDEX",
15935
+ qualrelname);
15936
+
15874
15937
/*
15875
15938
* in binary upgrade mode, update the catalog with any missing values
15876
15939
* that might be present.
@@ -16375,6 +16438,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16375
16438
PQExpBuffer q;
16376
16439
PQExpBuffer delq;
16377
16440
char *qindxname;
16441
+ char *qqindxname;
16378
16442
16379
16443
if (dopt->dataOnly)
16380
16444
return;
@@ -16383,6 +16447,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16383
16447
delq = createPQExpBuffer();
16384
16448
16385
16449
qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
16450
+ qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
16386
16451
16387
16452
/*
16388
16453
* If there's an associated constraint, don't dump the index per se, but
@@ -16435,8 +16500,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16435
16500
16436
16501
for (j = 0; j < nstatcols; j++)
16437
16502
{
16438
- appendPQExpBuffer(q, "ALTER INDEX %s ",
16439
- fmtQualifiedDumpable(indxinfo));
16503
+ appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
16440
16504
16441
16505
/*
16442
16506
* Note that this is a column number, so no quotes should be
@@ -16449,6 +16513,11 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16449
16513
}
16450
16514
}
16451
16515
16516
+ /* Indexes can depend on extensions */
16517
+ append_depends_on_extension(fout, q, &indxinfo->dobj,
16518
+ "pg_catalog.pg_class",
16519
+ "INDEX", qqindxname);
16520
+
16452
16521
/* If the index defines identity, we need to record that. */
16453
16522
if (indxinfo->indisreplident)
16454
16523
{
@@ -16459,8 +16528,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16459
16528
qindxname);
16460
16529
}
16461
16530
16462
- appendPQExpBuffer(delq, "DROP INDEX %s;\n",
16463
- fmtQualifiedDumpable(indxinfo));
16531
+ appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
16464
16532
16465
16533
if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
16466
16534
ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
@@ -16491,6 +16559,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
16491
16559
destroyPQExpBuffer(q);
16492
16560
destroyPQExpBuffer(delq);
16493
16561
free(qindxname);
16562
+ free(qqindxname);
16494
16563
}
16495
16564
16496
16565
/*
@@ -16729,6 +16798,11 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
16729
16798
fmtId(indxinfo->dobj.name));
16730
16799
}
16731
16800
16801
+ /* Indexes can depend on extensions */
16802
+ append_depends_on_extension(fout, q, &indxinfo->dobj,
16803
+ "pg_catalog.pg_class", "INDEX",
16804
+ fmtQualifiedDumpable(indxinfo));
16805
+
16732
16806
appendPQExpBuffer(delq, "ALTER TABLE ONLY %s ",
16733
16807
fmtQualifiedDumpable(tbinfo));
16734
16808
appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
@@ -17248,6 +17322,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17248
17322
PQExpBuffer query;
17249
17323
PQExpBuffer delqry;
17250
17324
PQExpBuffer trigprefix;
17325
+ PQExpBuffer trigidentity;
17251
17326
char *qtabname;
17252
17327
char *tgargs;
17253
17328
size_t lentgargs;
@@ -17265,13 +17340,14 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17265
17340
query = createPQExpBuffer();
17266
17341
delqry = createPQExpBuffer();
17267
17342
trigprefix = createPQExpBuffer();
17343
+ trigidentity = createPQExpBuffer();
17268
17344
17269
17345
qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
17270
17346
17271
- appendPQExpBuffer(delqry , "DROP TRIGGER %s ",
17272
- fmtId(tginfo->dobj.name ));
17273
- appendPQExpBuffer(delqry, "ON %s;\n",
17274
- fmtQualifiedDumpable(tbinfo) );
17347
+ appendPQExpBuffer(trigidentity , "%s ", fmtId(tginfo->dobj.name));
17348
+ appendPQExpBuffer(trigidentity, "ON %s", fmtQualifiedDumpable(tbinfo ));
17349
+
17350
+ appendPQExpBuffer(delqry, "DROP TRIGGER %s;\n", trigidentity->data );
17275
17351
17276
17352
if (tginfo->tgdef)
17277
17353
{
@@ -17390,6 +17466,11 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17390
17466
appendPQExpBufferStr(query, ");\n");
17391
17467
}
17392
17468
17469
+ /* Triggers can depend on extensions */
17470
+ append_depends_on_extension(fout, query, &tginfo->dobj,
17471
+ "pg_catalog.pg_trigger", "TRIGGER",
17472
+ trigidentity->data);
17473
+
17393
17474
if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17394
17475
{
17395
17476
appendPQExpBuffer(query, "\nALTER TABLE %s ",
@@ -17438,6 +17519,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17438
17519
destroyPQExpBuffer(query);
17439
17520
destroyPQExpBuffer(delqry);
17440
17521
destroyPQExpBuffer(trigprefix);
17522
+ destroyPQExpBuffer(trigidentity);
17441
17523
free(qtabname);
17442
17524
}
17443
17525
@@ -18087,6 +18169,15 @@ getDependencies(Archive *fout)
18087
18169
continue;
18088
18170
}
18089
18171
18172
+ /*
18173
+ * For 'x' dependencies, mark the object for later; we still add the
18174
+ * normal dependency, for possible ordering purposes. Currently
18175
+ * pg_dump_sort.c knows to put extensions ahead of all object types
18176
+ * that could possibly depend on them, but this is safer.
18177
+ */
18178
+ if (deptype == 'x')
18179
+ dobj->depends_on_ext = true;
18180
+
18090
18181
/*
18091
18182
* Ordinarily, table rowtypes have implicit dependencies on their
18092
18183
* tables. However, for a composite type the implicit dependency goes
0 commit comments