@@ -7998,6 +7998,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
79987998 i_tgconstrrelid,
79997999 i_tgconstrrelname,
80008000 i_tgenabled,
8001+ i_tgisinternal,
80018002 i_tgdeferrable,
80028003 i_tginitdeferred,
80038004 i_tgdef;
@@ -8016,18 +8017,63 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
80168017 tbinfo->dobj.name);
80178018
80188019 resetPQExpBuffer(query);
8019- if (fout->remoteVersion >= 90000 )
8020+ if (fout->remoteVersion >= 130000 )
80208021 {
80218022 /*
80228023 * NB: think not to use pretty=true in pg_get_triggerdef. It
80238024 * could result in non-forward-compatible dumps of WHEN clauses
80248025 * 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.
80258029 */
80268030 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 "
80318077 "FROM pg_catalog.pg_trigger t "
80328078 "WHERE tgrelid = '%u'::pg_catalog.oid "
80338079 "AND NOT tgisinternal",
@@ -8042,6 +8088,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
80428088 "SELECT tgname, "
80438089 "tgfoid::pg_catalog.regproc AS tgfname, "
80448090 "tgtype, tgnargs, tgargs, tgenabled, "
8091+ "false as tgisinternal, "
80458092 "tgisconstraint, tgconstrname, tgdeferrable, "
80468093 "tgconstrrelid, tginitdeferred, tableoid, oid, "
80478094 "tgconstrrelid::pg_catalog.regclass AS tgconstrrelname "
@@ -8090,6 +8137,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
80908137 i_tgconstrrelid = PQfnumber(res, "tgconstrrelid");
80918138 i_tgconstrrelname = PQfnumber(res, "tgconstrrelname");
80928139 i_tgenabled = PQfnumber(res, "tgenabled");
8140+ i_tgisinternal = PQfnumber(res, "tgisinternal");
80938141 i_tgdeferrable = PQfnumber(res, "tgdeferrable");
80948142 i_tginitdeferred = PQfnumber(res, "tginitdeferred");
80958143 i_tgdef = PQfnumber(res, "tgdef");
@@ -8109,6 +8157,7 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
81098157 tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
81108158 tginfo[j].tgtable = tbinfo;
81118159 tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
8160+ tginfo[j].tgisinternal = *(PQgetvalue(res, j, i_tgisinternal)) == 't';
81128161 if (i_tgdef >= 0)
81138162 {
81148163 tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
@@ -17799,7 +17848,40 @@ dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
1779917848 "pg_catalog.pg_trigger", "TRIGGER",
1780017849 trigidentity->data);
1780117850
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')
1780317885 {
1780417886 appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
1780517887 tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
0 commit comments