@@ -7816,6 +7816,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7816
7816
i_tgconstrrelid,
7817
7817
i_tgconstrrelname,
7818
7818
i_tgenabled,
7819
+ i_tgisinternal,
7819
7820
i_tgdeferrable,
7820
7821
i_tginitdeferred,
7821
7822
i_tgdef;
@@ -7834,18 +7835,63 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7834
7835
tbinfo->dobj.name);
7835
7836
7836
7837
resetPQExpBuffer(query);
7837
- if (fout->remoteVersion >= 90000 )
7838
+ if (fout->remoteVersion >= 130000 )
7838
7839
{
7839
7840
/*
7840
7841
* NB: think not to use pretty=true in pg_get_triggerdef. It
7841
7842
* could result in non-forward-compatible dumps of WHEN clauses
7842
7843
* due to under-parenthesization.
7844
+ *
7845
+ * NB: We need to see tgisinternal triggers in partitions, in case
7846
+ * the tgenabled flag has been changed from the parent.
7843
7847
*/
7844
7848
appendPQExpBuffer(query,
7845
- "SELECT tgname, "
7846
- "tgfoid::pg_catalog.regproc AS tgfname, "
7847
- "pg_catalog.pg_get_triggerdef(oid, false) AS tgdef, "
7848
- "tgenabled, tableoid, oid "
7849
+ "SELECT t.tgname, "
7850
+ "t.tgfoid::pg_catalog.regproc AS tgfname, "
7851
+ "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
7852
+ "t.tgenabled, t.tableoid, t.oid, t.tgisinternal "
7853
+ "FROM pg_catalog.pg_trigger t "
7854
+ "LEFT JOIN pg_catalog.pg_trigger u ON u.oid = t.tgparentid "
7855
+ "WHERE t.tgrelid = '%u'::pg_catalog.oid "
7856
+ "AND (NOT t.tgisinternal OR t.tgenabled != u.tgenabled)",
7857
+ tbinfo->dobj.catId.oid);
7858
+ }
7859
+ else if (fout->remoteVersion >= 110000)
7860
+ {
7861
+ /*
7862
+ * NB: We need to see tgisinternal triggers in partitions, in case
7863
+ * the tgenabled flag has been changed from the parent. No
7864
+ * tgparentid in version 11-12, so we have to match them via
7865
+ * pg_depend.
7866
+ *
7867
+ * See above about pretty=true in pg_get_triggerdef.
7868
+ */
7869
+ appendPQExpBuffer(query,
7870
+ "SELECT t.tgname, "
7871
+ "t.tgfoid::pg_catalog.regproc AS tgfname, "
7872
+ "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
7873
+ "t.tgenabled, t.tableoid, t.oid, t.tgisinternal "
7874
+ "FROM pg_catalog.pg_trigger t "
7875
+ "LEFT JOIN pg_catalog.pg_depend AS d ON "
7876
+ " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
7877
+ " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
7878
+ " d.objid = t.oid "
7879
+ "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
7880
+ "WHERE t.tgrelid = '%u'::pg_catalog.oid "
7881
+ "AND (NOT t.tgisinternal%s)",
7882
+ tbinfo->dobj.catId.oid,
7883
+ tbinfo->ispartition ?
7884
+ " OR t.tgenabled != pt.tgenabled" : "");
7885
+ }
7886
+ else if (fout->remoteVersion >= 90000)
7887
+ {
7888
+ /* See above about pretty=true in pg_get_triggerdef */
7889
+ appendPQExpBuffer(query,
7890
+ "SELECT t.tgname, "
7891
+ "t.tgfoid::pg_catalog.regproc AS tgfname, "
7892
+ "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
7893
+ "t.tgenabled, false as tgisinternal, "
7894
+ "t.tableoid, t.oid "
7849
7895
"FROM pg_catalog.pg_trigger t "
7850
7896
"WHERE tgrelid = '%u'::pg_catalog.oid "
7851
7897
"AND NOT tgisinternal",
@@ -7860,6 +7906,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7860
7906
"SELECT tgname, "
7861
7907
"tgfoid::pg_catalog.regproc AS tgfname, "
7862
7908
"tgtype, tgnargs, tgargs, tgenabled, "
7909
+ "false as tgisinternal, "
7863
7910
"tgisconstraint, tgconstrname, tgdeferrable, "
7864
7911
"tgconstrrelid, tginitdeferred, tableoid, oid, "
7865
7912
"tgconstrrelid::pg_catalog.regclass AS tgconstrrelname "
@@ -7908,6 +7955,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7908
7955
i_tgconstrrelid = PQfnumber(res, "tgconstrrelid");
7909
7956
i_tgconstrrelname = PQfnumber(res, "tgconstrrelname");
7910
7957
i_tgenabled = PQfnumber(res, "tgenabled");
7958
+ i_tgisinternal = PQfnumber(res, "tgisinternal");
7911
7959
i_tgdeferrable = PQfnumber(res, "tgdeferrable");
7912
7960
i_tginitdeferred = PQfnumber(res, "tginitdeferred");
7913
7961
i_tgdef = PQfnumber(res, "tgdef");
@@ -7927,6 +7975,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7927
7975
tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
7928
7976
tginfo[j].tgtable = tbinfo;
7929
7977
tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
7978
+ tginfo[j].tgisinternal = *(PQgetvalue(res, j, i_tgisinternal)) == 't';
7930
7979
if (i_tgdef >= 0)
7931
7980
{
7932
7981
tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
@@ -17681,7 +17730,40 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
17681
17730
"pg_catalog.pg_trigger", "TRIGGER",
17682
17731
trigidentity->data);
17683
17732
17684
- if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17733
+ if (tginfo->tgisinternal)
17734
+ {
17735
+ /*
17736
+ * Triggers marked internal only appear here because their 'tgenabled'
17737
+ * flag differs from its parent's. The trigger is created already, so
17738
+ * remove the CREATE and replace it with an ALTER. (Clear out the
17739
+ * DROP query too, so that pg_dump --create does not cause errors.)
17740
+ */
17741
+ resetPQExpBuffer(query);
17742
+ resetPQExpBuffer(delqry);
17743
+ appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
17744
+ tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
17745
+ fmtQualifiedDumpable(tbinfo));
17746
+ switch (tginfo->tgenabled)
17747
+ {
17748
+ case 'f':
17749
+ case 'D':
17750
+ appendPQExpBufferStr(query, "DISABLE");
17751
+ break;
17752
+ case 't':
17753
+ case 'O':
17754
+ appendPQExpBufferStr(query, "ENABLE");
17755
+ break;
17756
+ case 'R':
17757
+ appendPQExpBufferStr(query, "ENABLE REPLICA");
17758
+ break;
17759
+ case 'A':
17760
+ appendPQExpBufferStr(query, "ENABLE ALWAYS");
17761
+ break;
17762
+ }
17763
+ appendPQExpBuffer(query, " TRIGGER %s;\n",
17764
+ fmtId(tginfo->dobj.name));
17765
+ }
17766
+ else if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17685
17767
{
17686
17768
appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
17687
17769
tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
0 commit comments