@@ -7946,6 +7946,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7946
7946
i_tgconstrrelid,
7947
7947
i_tgconstrrelname,
7948
7948
i_tgenabled,
7949
+ i_tgisinternal,
7949
7950
i_tgdeferrable,
7950
7951
i_tginitdeferred,
7951
7952
i_tgdef;
@@ -7964,18 +7965,63 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7964
7965
tbinfo->dobj.name);
7965
7966
7966
7967
resetPQExpBuffer(query);
7967
- if (fout->remoteVersion >= 90000 )
7968
+ if (fout->remoteVersion >= 130000 )
7968
7969
{
7969
7970
/*
7970
7971
* NB: think not to use pretty=true in pg_get_triggerdef. It
7971
7972
* could result in non-forward-compatible dumps of WHEN clauses
7972
7973
* due to under-parenthesization.
7974
+ *
7975
+ * NB: We need to see tgisinternal triggers in partitions, in case
7976
+ * the tgenabled flag has been changed from the parent.
7973
7977
*/
7974
7978
appendPQExpBuffer(query,
7975
- "SELECT tgname, "
7976
- "tgfoid::pg_catalog.regproc AS tgfname, "
7977
- "pg_catalog.pg_get_triggerdef(oid, false) AS tgdef, "
7978
- "tgenabled, tableoid, oid "
7979
+ "SELECT t.tgname, "
7980
+ "t.tgfoid::pg_catalog.regproc AS tgfname, "
7981
+ "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
7982
+ "t.tgenabled, t.tableoid, t.oid, t.tgisinternal "
7983
+ "FROM pg_catalog.pg_trigger t "
7984
+ "LEFT JOIN pg_catalog.pg_trigger u ON u.oid = t.tgparentid "
7985
+ "WHERE t.tgrelid = '%u'::pg_catalog.oid "
7986
+ "AND (NOT t.tgisinternal OR t.tgenabled != u.tgenabled)",
7987
+ tbinfo->dobj.catId.oid);
7988
+ }
7989
+ else if (fout->remoteVersion >= 110000)
7990
+ {
7991
+ /*
7992
+ * NB: We need to see tgisinternal triggers in partitions, in case
7993
+ * the tgenabled flag has been changed from the parent. No
7994
+ * tgparentid in version 11-12, so we have to match them via
7995
+ * pg_depend.
7996
+ *
7997
+ * See above about pretty=true in pg_get_triggerdef.
7998
+ */
7999
+ appendPQExpBuffer(query,
8000
+ "SELECT t.tgname, "
8001
+ "t.tgfoid::pg_catalog.regproc AS tgfname, "
8002
+ "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8003
+ "t.tgenabled, t.tableoid, t.oid, t.tgisinternal "
8004
+ "FROM pg_catalog.pg_trigger t "
8005
+ "LEFT JOIN pg_catalog.pg_depend AS d ON "
8006
+ " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8007
+ " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8008
+ " d.objid = t.oid "
8009
+ "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
8010
+ "WHERE t.tgrelid = '%u'::pg_catalog.oid "
8011
+ "AND (NOT t.tgisinternal%s)",
8012
+ tbinfo->dobj.catId.oid,
8013
+ tbinfo->ispartition ?
8014
+ " OR t.tgenabled != pt.tgenabled" : "");
8015
+ }
8016
+ else if (fout->remoteVersion >= 90000)
8017
+ {
8018
+ /* See above about pretty=true in pg_get_triggerdef */
8019
+ appendPQExpBuffer(query,
8020
+ "SELECT t.tgname, "
8021
+ "t.tgfoid::pg_catalog.regproc AS tgfname, "
8022
+ "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8023
+ "t.tgenabled, false as tgisinternal, "
8024
+ "t.tableoid, t.oid "
7979
8025
"FROM pg_catalog.pg_trigger t "
7980
8026
"WHERE tgrelid = '%u'::pg_catalog.oid "
7981
8027
"AND NOT tgisinternal",
@@ -7990,6 +8036,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7990
8036
"SELECT tgname, "
7991
8037
"tgfoid::pg_catalog.regproc AS tgfname, "
7992
8038
"tgtype, tgnargs, tgargs, tgenabled, "
8039
+ "false as tgisinternal, "
7993
8040
"tgisconstraint, tgconstrname, tgdeferrable, "
7994
8041
"tgconstrrelid, tginitdeferred, tableoid, oid, "
7995
8042
"tgconstrrelid::pg_catalog.regclass AS tgconstrrelname "
@@ -8038,6 +8085,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
8038
8085
i_tgconstrrelid = PQfnumber(res, "tgconstrrelid");
8039
8086
i_tgconstrrelname = PQfnumber(res, "tgconstrrelname");
8040
8087
i_tgenabled = PQfnumber(res, "tgenabled");
8088
+ i_tgisinternal = PQfnumber(res, "tgisinternal");
8041
8089
i_tgdeferrable = PQfnumber(res, "tgdeferrable");
8042
8090
i_tginitdeferred = PQfnumber(res, "tginitdeferred");
8043
8091
i_tgdef = PQfnumber(res, "tgdef");
@@ -8057,6 +8105,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
8057
8105
tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
8058
8106
tginfo[j].tgtable = tbinfo;
8059
8107
tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
8108
+ tginfo[j].tgisinternal = *(PQgetvalue(res, j, i_tgisinternal)) == 't';
8060
8109
if (i_tgdef >= 0)
8061
8110
{
8062
8111
tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
@@ -17691,7 +17740,40 @@ dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
17691
17740
"pg_catalog.pg_trigger", "TRIGGER",
17692
17741
trigidentity->data);
17693
17742
17694
- if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17743
+ if (tginfo->tgisinternal)
17744
+ {
17745
+ /*
17746
+ * Triggers marked internal only appear here because their 'tgenabled'
17747
+ * flag differs from its parent's. The trigger is created already, so
17748
+ * remove the CREATE and replace it with an ALTER. (Clear out the
17749
+ * DROP query too, so that pg_dump --create does not cause errors.)
17750
+ */
17751
+ resetPQExpBuffer(query);
17752
+ resetPQExpBuffer(delqry);
17753
+ appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
17754
+ tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
17755
+ fmtQualifiedDumpable(tbinfo));
17756
+ switch (tginfo->tgenabled)
17757
+ {
17758
+ case 'f':
17759
+ case 'D':
17760
+ appendPQExpBufferStr(query, "DISABLE");
17761
+ break;
17762
+ case 't':
17763
+ case 'O':
17764
+ appendPQExpBufferStr(query, "ENABLE");
17765
+ break;
17766
+ case 'R':
17767
+ appendPQExpBufferStr(query, "ENABLE REPLICA");
17768
+ break;
17769
+ case 'A':
17770
+ appendPQExpBufferStr(query, "ENABLE ALWAYS");
17771
+ break;
17772
+ }
17773
+ appendPQExpBuffer(query, " TRIGGER %s;\n",
17774
+ fmtId(tginfo->dobj.name));
17775
+ }
17776
+ else if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17695
17777
{
17696
17778
appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
17697
17779
tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
0 commit comments