@@ -7998,6 +7998,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
7998
7998
i_tgconstrrelid,
7999
7999
i_tgconstrrelname,
8000
8000
i_tgenabled,
8001
+ i_tgisinternal,
8001
8002
i_tgdeferrable,
8002
8003
i_tginitdeferred,
8003
8004
i_tgdef;
@@ -8016,18 +8017,63 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
8016
8017
tbinfo->dobj.name);
8017
8018
8018
8019
resetPQExpBuffer(query);
8019
- if (fout->remoteVersion >= 90000 )
8020
+ if (fout->remoteVersion >= 130000 )
8020
8021
{
8021
8022
/*
8022
8023
* NB: think not to use pretty=true in pg_get_triggerdef. It
8023
8024
* could result in non-forward-compatible dumps of WHEN clauses
8024
8025
* due to under-parenthesization.
8026
+ *
8027
+ * NB: We need to see tgisinternal triggers in partitions, in case
8028
+ * the tgenabled flag has been changed from the parent.
8025
8029
*/
8026
8030
appendPQExpBuffer(query,
8027
- "SELECT tgname, "
8028
- "tgfoid::pg_catalog.regproc AS tgfname, "
8029
- "pg_catalog.pg_get_triggerdef(oid, false) AS tgdef, "
8030
- "tgenabled, tableoid, oid "
8031
+ "SELECT t.tgname, "
8032
+ "t.tgfoid::pg_catalog.regproc AS tgfname, "
8033
+ "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8034
+ "t.tgenabled, t.tableoid, t.oid, t.tgisinternal "
8035
+ "FROM pg_catalog.pg_trigger t "
8036
+ "LEFT JOIN pg_catalog.pg_trigger u ON u.oid = t.tgparentid "
8037
+ "WHERE t.tgrelid = '%u'::pg_catalog.oid "
8038
+ "AND (NOT t.tgisinternal OR t.tgenabled != u.tgenabled)",
8039
+ tbinfo->dobj.catId.oid);
8040
+ }
8041
+ else if (fout->remoteVersion >= 110000)
8042
+ {
8043
+ /*
8044
+ * NB: We need to see tgisinternal triggers in partitions, in case
8045
+ * the tgenabled flag has been changed from the parent. No
8046
+ * tgparentid in version 11-12, so we have to match them via
8047
+ * pg_depend.
8048
+ *
8049
+ * See above about pretty=true in pg_get_triggerdef.
8050
+ */
8051
+ appendPQExpBuffer(query,
8052
+ "SELECT t.tgname, "
8053
+ "t.tgfoid::pg_catalog.regproc AS tgfname, "
8054
+ "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8055
+ "t.tgenabled, t.tableoid, t.oid, t.tgisinternal "
8056
+ "FROM pg_catalog.pg_trigger t "
8057
+ "LEFT JOIN pg_catalog.pg_depend AS d ON "
8058
+ " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8059
+ " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
8060
+ " d.objid = t.oid "
8061
+ "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
8062
+ "WHERE t.tgrelid = '%u'::pg_catalog.oid "
8063
+ "AND (NOT t.tgisinternal%s)",
8064
+ tbinfo->dobj.catId.oid,
8065
+ tbinfo->ispartition ?
8066
+ " OR t.tgenabled != pt.tgenabled" : "");
8067
+ }
8068
+ else if (fout->remoteVersion >= 90000)
8069
+ {
8070
+ /* See above about pretty=true in pg_get_triggerdef */
8071
+ appendPQExpBuffer(query,
8072
+ "SELECT t.tgname, "
8073
+ "t.tgfoid::pg_catalog.regproc AS tgfname, "
8074
+ "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
8075
+ "t.tgenabled, false as tgisinternal, "
8076
+ "t.tableoid, t.oid "
8031
8077
"FROM pg_catalog.pg_trigger t "
8032
8078
"WHERE tgrelid = '%u'::pg_catalog.oid "
8033
8079
"AND NOT tgisinternal",
@@ -8042,6 +8088,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
8042
8088
"SELECT tgname, "
8043
8089
"tgfoid::pg_catalog.regproc AS tgfname, "
8044
8090
"tgtype, tgnargs, tgargs, tgenabled, "
8091
+ "false as tgisinternal, "
8045
8092
"tgisconstraint, tgconstrname, tgdeferrable, "
8046
8093
"tgconstrrelid, tginitdeferred, tableoid, oid, "
8047
8094
"tgconstrrelid::pg_catalog.regclass AS tgconstrrelname "
@@ -8090,6 +8137,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
8090
8137
i_tgconstrrelid = PQfnumber(res, "tgconstrrelid");
8091
8138
i_tgconstrrelname = PQfnumber(res, "tgconstrrelname");
8092
8139
i_tgenabled = PQfnumber(res, "tgenabled");
8140
+ i_tgisinternal = PQfnumber(res, "tgisinternal");
8093
8141
i_tgdeferrable = PQfnumber(res, "tgdeferrable");
8094
8142
i_tginitdeferred = PQfnumber(res, "tginitdeferred");
8095
8143
i_tgdef = PQfnumber(res, "tgdef");
@@ -8109,6 +8157,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
8109
8157
tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
8110
8158
tginfo[j].tgtable = tbinfo;
8111
8159
tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
8160
+ tginfo[j].tgisinternal = *(PQgetvalue(res, j, i_tgisinternal)) == 't';
8112
8161
if (i_tgdef >= 0)
8113
8162
{
8114
8163
tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
@@ -17799,7 +17848,40 @@ dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
17799
17848
"pg_catalog.pg_trigger", "TRIGGER",
17800
17849
trigidentity->data);
17801
17850
17802
- if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17851
+ if (tginfo->tgisinternal)
17852
+ {
17853
+ /*
17854
+ * Triggers marked internal only appear here because their 'tgenabled'
17855
+ * flag differs from its parent's. The trigger is created already, so
17856
+ * remove the CREATE and replace it with an ALTER. (Clear out the
17857
+ * DROP query too, so that pg_dump --create does not cause errors.)
17858
+ */
17859
+ resetPQExpBuffer(query);
17860
+ resetPQExpBuffer(delqry);
17861
+ appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
17862
+ tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
17863
+ fmtQualifiedDumpable(tbinfo));
17864
+ switch (tginfo->tgenabled)
17865
+ {
17866
+ case 'f':
17867
+ case 'D':
17868
+ appendPQExpBufferStr(query, "DISABLE");
17869
+ break;
17870
+ case 't':
17871
+ case 'O':
17872
+ appendPQExpBufferStr(query, "ENABLE");
17873
+ break;
17874
+ case 'R':
17875
+ appendPQExpBufferStr(query, "ENABLE REPLICA");
17876
+ break;
17877
+ case 'A':
17878
+ appendPQExpBufferStr(query, "ENABLE ALWAYS");
17879
+ break;
17880
+ }
17881
+ appendPQExpBuffer(query, " TRIGGER %s;\n",
17882
+ fmtId(tginfo->dobj.name));
17883
+ }
17884
+ else if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
17803
17885
{
17804
17886
appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
17805
17887
tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
0 commit comments