@@ -7570,6 +7570,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7570
7570
i_tgconstrrelid,
7571
7571
i_tgconstrrelname,
7572
7572
i_tgenabled,
7573
+ i_tgisinternal,
7573
7574
i_tgdeferrable,
7574
7575
i_tginitdeferred,
7575
7576
i_tgdef;
@@ -7589,18 +7590,63 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7589
7590
tbinfo->dobj.name);
7590
7591
7591
7592
resetPQExpBuffer(query);
7592
- if (fout->remoteVersion >= 90000 )
7593
+ if (fout->remoteVersion >= 130000 )
7593
7594
{
7594
7595
/*
7595
7596
* NB: think not to use pretty=true in pg_get_triggerdef. It
7596
7597
* could result in non-forward-compatible dumps of WHEN clauses
7597
7598
* due to under-parenthesization.
7599
+ *
7600
+ * NB: We need to see tgisinternal triggers in partitions, in case
7601
+ * the tgenabled flag has been changed from the parent.
7598
7602
*/
7599
7603
appendPQExpBuffer(query,
7600
- "SELECT tgname, "
7601
- "tgfoid::pg_catalog.regproc AS tgfname, "
7602
- "pg_catalog.pg_get_triggerdef(oid, false) AS tgdef, "
7603
- "tgenabled, tableoid, oid "
7604
+ "SELECT t.tgname, "
7605
+ "t.tgfoid::pg_catalog.regproc AS tgfname, "
7606
+ "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
7607
+ "t.tgenabled, t.tableoid, t.oid, t.tgisinternal "
7608
+ "FROM pg_catalog.pg_trigger t "
7609
+ "LEFT JOIN pg_catalog.pg_trigger u ON u.oid = t.tgparentid "
7610
+ "WHERE t.tgrelid = '%u'::pg_catalog.oid "
7611
+ "AND (NOT t.tgisinternal OR t.tgenabled != u.tgenabled)",
7612
+ tbinfo->dobj.catId.oid);
7613
+ }
7614
+ else if (fout->remoteVersion >= 110000)
7615
+ {
7616
+ /*
7617
+ * NB: We need to see tgisinternal triggers in partitions, in case
7618
+ * the tgenabled flag has been changed from the parent. No
7619
+ * tgparentid in version 11-12, so we have to match them via
7620
+ * pg_depend.
7621
+ *
7622
+ * See above about pretty=true in pg_get_triggerdef.
7623
+ */
7624
+ appendPQExpBuffer(query,
7625
+ "SELECT t.tgname, "
7626
+ "t.tgfoid::pg_catalog.regproc AS tgfname, "
7627
+ "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
7628
+ "t.tgenabled, t.tableoid, t.oid, t.tgisinternal "
7629
+ "FROM pg_catalog.pg_trigger t "
7630
+ "LEFT JOIN pg_catalog.pg_depend AS d ON "
7631
+ " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
7632
+ " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
7633
+ " d.objid = t.oid "
7634
+ "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
7635
+ "WHERE t.tgrelid = '%u'::pg_catalog.oid "
7636
+ "AND (NOT t.tgisinternal%s)",
7637
+ tbinfo->dobj.catId.oid,
7638
+ tbinfo->ispartition ?
7639
+ " OR t.tgenabled != pt.tgenabled" : "");
7640
+ }
7641
+ else if (fout->remoteVersion >= 90000)
7642
+ {
7643
+ /* See above about pretty=true in pg_get_triggerdef */
7644
+ appendPQExpBuffer(query,
7645
+ "SELECT t.tgname, "
7646
+ "t.tgfoid::pg_catalog.regproc AS tgfname, "
7647
+ "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
7648
+ "t.tgenabled, false as tgisinternal, "
7649
+ "t.tableoid, t.oid "
7604
7650
"FROM pg_catalog.pg_trigger t "
7605
7651
"WHERE tgrelid = '%u'::pg_catalog.oid "
7606
7652
"AND NOT tgisinternal",
@@ -7615,6 +7661,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7615
7661
"SELECT tgname, "
7616
7662
"tgfoid::pg_catalog.regproc AS tgfname, "
7617
7663
"tgtype, tgnargs, tgargs, tgenabled, "
7664
+ "false as tgisinternal, "
7618
7665
"tgisconstraint, tgconstrname, tgdeferrable, "
7619
7666
"tgconstrrelid, tginitdeferred, tableoid, oid, "
7620
7667
"tgconstrrelid::pg_catalog.regclass AS tgconstrrelname "
@@ -7663,6 +7710,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7663
7710
i_tgconstrrelid = PQfnumber(res, "tgconstrrelid");
7664
7711
i_tgconstrrelname = PQfnumber(res, "tgconstrrelname");
7665
7712
i_tgenabled = PQfnumber(res, "tgenabled");
7713
+ i_tgisinternal = PQfnumber(res, "tgisinternal");
7666
7714
i_tgdeferrable = PQfnumber(res, "tgdeferrable");
7667
7715
i_tginitdeferred = PQfnumber(res, "tginitdeferred");
7668
7716
i_tgdef = PQfnumber(res, "tgdef");
@@ -7682,6 +7730,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7682
7730
tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
7683
7731
tginfo[j].tgtable = tbinfo;
7684
7732
tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
7733
+ tginfo[j].tgisinternal = *(PQgetvalue(res, j, i_tgisinternal)) == 't';
7685
7734
if (i_tgdef >= 0)
7686
7735
{
7687
7736
tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
@@ -17419,7 +17468,40 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17419
17468
"pg_catalog.pg_trigger", "TRIGGER",
17420
17469
trigidentity->data);
17421
17470
17422
- if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17471
+ if (tginfo->tgisinternal)
17472
+ {
17473
+ /*
17474
+ * Triggers marked internal only appear here because their 'tgenabled'
17475
+ * flag differs from its parent's. The trigger is created already, so
17476
+ * remove the CREATE and replace it with an ALTER. (Clear out the
17477
+ * DROP query too, so that pg_dump --create does not cause errors.)
17478
+ */
17479
+ resetPQExpBuffer(query);
17480
+ resetPQExpBuffer(delqry);
17481
+ appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
17482
+ tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
17483
+ fmtQualifiedDumpable(tbinfo));
17484
+ switch (tginfo->tgenabled)
17485
+ {
17486
+ case 'f':
17487
+ case 'D':
17488
+ appendPQExpBufferStr(query, "DISABLE");
17489
+ break;
17490
+ case 't':
17491
+ case 'O':
17492
+ appendPQExpBufferStr(query, "ENABLE");
17493
+ break;
17494
+ case 'R':
17495
+ appendPQExpBufferStr(query, "ENABLE REPLICA");
17496
+ break;
17497
+ case 'A':
17498
+ appendPQExpBufferStr(query, "ENABLE ALWAYS");
17499
+ break;
17500
+ }
17501
+ appendPQExpBuffer(query, " TRIGGER %s;\n",
17502
+ fmtId(tginfo->dobj.name));
17503
+ }
17504
+ else if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17423
17505
{
17424
17506
appendPQExpBuffer(query, "\nALTER TABLE %s ",
17425
17507
fmtQualifiedDumpable(tbinfo));
0 commit comments