From 9b58975ebf44b17a887396de0722bc1d618b493f Mon Sep 17 00:00:00 2001
From: Fujii Masao <fujii@postgresql.org>
Date: Fri, 24 Jul 2026 10:41:40 +0900
Subject: [PATCH v3 2/3] Collect ALTER PUBLICATION SET ALL commands for event
 triggers

Previously, ALTER PUBLICATION ... SET ALL TABLES and
SET ALL SEQUENCES fired ddl_command_end, but
pg_event_trigger_ddl_commands() could return no entry for the altered
publication because none was collected.

Fix this by collecting the publication itself as the
ALTER PUBLICATION command whenever a SET ALL command changes the
publication state.

As a side-effect of this fix, SET ALL TABLES with EXCEPT entries may now
produce both a publication-level ALTER PUBLICATION entry and the existing
per-membership entries for added exclusions. This is intentional, since
they represent different parts of the command.

Backpatch to v19, where ALTER PUBLICATION SET ALL TABLES and
SET ALL SEQUENCES were introduced.
---
 src/backend/commands/publicationcmds.c      | 11 +++++++----
 src/test/regress/expected/event_trigger.out |  9 +++++++++
 src/test/regress/sql/event_trigger.sql      |  5 +++++
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index ebb7750ee30..601ae091e32 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -1607,7 +1607,7 @@ CheckAlterPublication(AlterPublicationStmt *stmt, HeapTuple tup,
 /*
  * Update FOR ALL TABLES / FOR ALL SEQUENCES flags of a publication.
  */
-static void
+static bool
 AlterPublicationAllFlags(AlterPublicationStmt *stmt, Relation rel,
 						 HeapTuple tup)
 {
@@ -1618,7 +1618,7 @@ AlterPublicationAllFlags(AlterPublicationStmt *stmt, Relation rel,
 	bool		dirty = false;
 
 	if (!stmt->for_all_tables && !stmt->for_all_sequences)
-		return;
+		return false;
 
 	pubform = (Form_pg_publication) GETSTRUCT(tup);
 
@@ -1651,6 +1651,8 @@ AlterPublicationAllFlags(AlterPublicationStmt *stmt, Relation rel,
 		if (replaces[Anum_pg_publication_puballtables - 1])
 			CacheInvalidateRelcacheAll();
 	}
+
+	return dirty;
 }
 
 /*
@@ -1694,6 +1696,7 @@ AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt)
 		Oid			pubid = pubform->oid;
 		bool		tables_dropped;
 		bool		schemas_dropped;
+		bool		all_flags_changed;
 
 		ObjectsInPublicationToOids(stmt->pubobjects, pstate, &relations,
 								   &exceptrelations, &schemaidlist);
@@ -1724,9 +1727,9 @@ AlterPublication(ParseState *pstate, AlterPublicationStmt *stmt)
 			AlterPublicationTables(stmt, tup, relations, pstate->p_sourcetext,
 								   schemaidlist != NIL);
 		schemas_dropped = AlterPublicationSchemas(stmt, tup, schemaidlist);
-		AlterPublicationAllFlags(stmt, rel, tup);
+		all_flags_changed = AlterPublicationAllFlags(stmt, rel, tup);
 
-		if (tables_dropped || schemas_dropped)
+		if (tables_dropped || schemas_dropped || all_flags_changed)
 		{
 			ObjectAddress obj;
 
diff --git a/src/test/regress/expected/event_trigger.out b/src/test/regress/expected/event_trigger.out
index 44503e6d0bd..0e57c2d4eb1 100644
--- a/src/test/regress/expected/event_trigger.out
+++ b/src/test/regress/expected/event_trigger.out
@@ -463,6 +463,14 @@ ALTER PUBLICATION evttrig_pub SET TABLE evttrig_pub_tbl2;
 NOTICE:  NORMAL: orig=t normal=f istemp=f type=publication namespace identity=evttrig_pub_schema2 in publication evttrig_pub schema=<NULL> name=<NULL> addr={evttrig_pub_schema2} args={evttrig_pub}
 NOTICE:  NORMAL: orig=t normal=f istemp=f type=publication relation identity=public.evttrig_pub_tbl3 in publication evttrig_pub schema=<NULL> name=<NULL> addr={public,evttrig_pub_tbl3} args={evttrig_pub}
 NOTICE:  END: command_tag=ALTER PUBLICATION type=publication identity=evttrig_pub
+CREATE PUBLICATION evttrig_all_pub;
+NOTICE:  END: command_tag=CREATE PUBLICATION type=publication identity=evttrig_all_pub
+ALTER PUBLICATION evttrig_all_pub SET ALL TABLES EXCEPT (TABLE evttrig_pub_tbl);
+NOTICE:  END: command_tag=ALTER PUBLICATION type=publication relation identity=public.evttrig_pub_tbl in publication evttrig_all_pub
+NOTICE:  END: command_tag=ALTER PUBLICATION type=publication identity=evttrig_all_pub
+ALTER PUBLICATION evttrig_all_pub SET ALL SEQUENCES;
+NOTICE:  NORMAL: orig=t normal=f istemp=f type=publication relation identity=public.evttrig_pub_tbl in publication evttrig_all_pub schema=<NULL> name=<NULL> addr={public,evttrig_pub_tbl} args={evttrig_all_pub}
+NOTICE:  END: command_tag=ALTER PUBLICATION type=publication identity=evttrig_all_pub
 CREATE SCHEMA evttrig
 	CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two', col_c SERIAL)
 	CREATE INDEX one_idx ON one (col_b)
@@ -620,6 +628,7 @@ NOTICE:  END: command_tag=CREATE OPERATOR CLASS type=operator class identity=pub
 DROP EVENT TRIGGER regress_event_trigger_report_dropped;
 DROP EVENT TRIGGER regress_event_trigger_report_end;
 DROP PUBLICATION evttrig_pub;
+DROP PUBLICATION evttrig_all_pub;
 DROP TABLE evttrig_pub_tbl;
 DROP TABLE evttrig_pub_tbl2;
 DROP TABLE evttrig_pub_tbl3;
diff --git a/src/test/regress/sql/event_trigger.sql b/src/test/regress/sql/event_trigger.sql
index 34bd0c23fa9..85c961caef4 100644
--- a/src/test/regress/sql/event_trigger.sql
+++ b/src/test/regress/sql/event_trigger.sql
@@ -353,6 +353,10 @@ ALTER PUBLICATION evttrig_pub DROP TABLE evttrig_pub_tbl;
 ALTER PUBLICATION evttrig_pub DROP TABLES IN SCHEMA evttrig_pub_schema;
 ALTER PUBLICATION evttrig_pub SET TABLE evttrig_pub_tbl2;
 
+CREATE PUBLICATION evttrig_all_pub;
+ALTER PUBLICATION evttrig_all_pub SET ALL TABLES EXCEPT (TABLE evttrig_pub_tbl);
+ALTER PUBLICATION evttrig_all_pub SET ALL SEQUENCES;
+
 CREATE SCHEMA evttrig
 	CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two', col_c SERIAL)
 	CREATE INDEX one_idx ON one (col_b)
@@ -436,6 +440,7 @@ DROP EVENT TRIGGER regress_event_trigger_report_dropped;
 DROP EVENT TRIGGER regress_event_trigger_report_end;
 
 DROP PUBLICATION evttrig_pub;
+DROP PUBLICATION evttrig_all_pub;
 DROP TABLE evttrig_pub_tbl;
 DROP TABLE evttrig_pub_tbl2;
 DROP TABLE evttrig_pub_tbl3;
-- 
2.37.1 (Apple Git-137.1)

