From 3426508a69882eaeff51a5a363b277ff5174630f Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Mon, 9 Feb 2026 15:36:35 +0800
Subject: [PATCH v7 2/2] CREATE TABLE LIKE INCLUDING TRIGGERS copies tgenabled

discussion: https://postgr.es/m/CACJufxHJAr2FjbeB6ghg_-N5dxX5JVnjKSLOUxOyt4TeaAWQkg@mail.gmail.com
commitfest: https://commitfest.postgresql.org/patch/6087
---
 src/backend/catalog/index.c            |  1 +
 src/backend/commands/tablecmds.c       |  4 ++++
 src/backend/commands/trigger.c         |  1 +
 src/backend/parser/gram.y              |  2 ++
 src/backend/tcop/utility.c             | 12 ++++++++----
 src/include/nodes/parsenodes.h         |  1 +
 src/test/regress/expected/triggers.out |  9 +++++++--
 src/test/regress/sql/triggers.sql      |  3 +++
 8 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index b0b5a886fa1..d4570626e0b 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -2021,6 +2021,7 @@ index_constraint_create(Relation heapRelation,
 		CreateTrigStmt *trigger = makeNode(CreateTrigStmt);
 
 		trigger->replace = false;
+		trigger->tgenabled = TRIGGER_FIRES_ON_ORIGIN;
 		trigger->isconstraint = true;
 		trigger->trigname = (constraintType == CONSTRAINT_PRIMARY) ?
 			"PK_ConstraintTrigger" :
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 6a25f6b7553..6c53df1e54a 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -13839,6 +13839,7 @@ CreateFKCheckTrigger(Oid myRelOid, Oid refRelOid, Constraint *fkconstraint,
 	 */
 	fk_trigger = makeNode(CreateTrigStmt);
 	fk_trigger->replace = false;
+	fk_trigger->tgenabled = TRIGGER_FIRES_ON_ORIGIN;
 	fk_trigger->isconstraint = true;
 	fk_trigger->trigname = "RI_ConstraintTrigger_c";
 	fk_trigger->relation = NULL;
@@ -13900,6 +13901,7 @@ createForeignKeyActionTriggers(Oid myRelOid, Oid refRelOid, Constraint *fkconstr
 	 */
 	fk_trigger = makeNode(CreateTrigStmt);
 	fk_trigger->replace = false;
+	fk_trigger->tgenabled = TRIGGER_FIRES_ON_ORIGIN;
 	fk_trigger->isconstraint = true;
 	fk_trigger->trigname = "RI_ConstraintTrigger_a";
 	fk_trigger->relation = NULL;
@@ -13962,6 +13964,7 @@ createForeignKeyActionTriggers(Oid myRelOid, Oid refRelOid, Constraint *fkconstr
 	 */
 	fk_trigger = makeNode(CreateTrigStmt);
 	fk_trigger->replace = false;
+	fk_trigger->tgenabled = TRIGGER_FIRES_ON_ORIGIN;
 	fk_trigger->isconstraint = true;
 	fk_trigger->trigname = "RI_ConstraintTrigger_a";
 	fk_trigger->relation = NULL;
@@ -20911,6 +20914,7 @@ CloneRowTriggersToPartition(Relation parent, Relation partition)
 
 		trigStmt = makeNode(CreateTrigStmt);
 		trigStmt->replace = false;
+		trigStmt->tgenabled = trigForm->tgenabled;
 		trigStmt->isconstraint = OidIsValid(trigForm->tgconstraint);
 		trigStmt->trigname = NameStr(trigForm->tgname);
 		trigStmt->relation = NULL;
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index e944265bd9f..280427559d4 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -6947,6 +6947,7 @@ generateClonedTriggerStmt(RangeVar *heapRel, Oid source_trigid,
 
 	trigStmt = makeNode(CreateTrigStmt);
 	trigStmt->replace = false;
+	trigStmt->tgenabled = trigForm->tgenabled;
 	trigStmt->isconstraint = OidIsValid(trigForm->tgconstraint);
 	trigStmt->trigname = pstrdup(NameStr(trigForm->tgname));
 	trigStmt->relation = heapRel;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index ee9cbbfc6c4..24b27d2c47d 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -6137,6 +6137,7 @@ CreateTrigStmt:
 					CreateTrigStmt *n = makeNode(CreateTrigStmt);
 
 					n->replace = $2;
+					n->tgenabled = TRIGGER_FIRES_ON_ORIGIN;
 					n->isconstraint = false;
 					n->trigname = $4;
 					n->relation = $8;
@@ -6188,6 +6189,7 @@ CreateTrigStmt:
 								(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 								 errmsg("CREATE OR REPLACE CONSTRAINT TRIGGER is not supported"),
 								 parser_errposition(@1)));
+					n->tgenabled = TRIGGER_FIRES_ON_ORIGIN;
 					n->isconstraint = true;
 					n->trigname = $5;
 					n->relation = $9;
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 34dd6e18df5..d240ecd4077 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1701,10 +1701,14 @@ ProcessUtilitySlow(ParseState *pstate,
 				break;
 
 			case T_CreateTrigStmt:
-				address = CreateTrigger((CreateTrigStmt *) parsetree,
-										queryString, InvalidOid, InvalidOid,
-										InvalidOid, InvalidOid, InvalidOid,
-										InvalidOid, NULL, false, false);
+				{
+					CreateTrigStmt *stmt = (CreateTrigStmt *) parsetree;
+
+					address = CreateTriggerFiringOn(stmt, queryString, InvalidOid, InvalidOid,
+													InvalidOid, InvalidOid, InvalidOid,
+													InvalidOid, NULL, false,
+													false, stmt->tgenabled);
+				}
 				break;
 
 			case T_CreatePLangStmt:
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 47e6dfb2ab2..e98cc8c289b 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -3137,6 +3137,7 @@ typedef struct CreateTrigStmt
 {
 	NodeTag		type;
 	bool		replace;		/* replace trigger if already exists */
+	char		tgenabled;		/* trigger's firing configuration */
 	bool		isconstraint;	/* This is a constraint trigger */
 	char	   *trigname;		/* TRIGGER's name */
 	RangeVar   *relation;		/* relation trigger is on */
diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out
index e8eef2022f3..9f405de807d 100644
--- a/src/test/regress/expected/triggers.out
+++ b/src/test/regress/expected/triggers.out
@@ -476,6 +476,9 @@ NOTICE:  dummy_update_func(afterb) called: action = UPDATE, old = (t), new = (f)
 UPDATE some_t SET some_col = TRUE;
 NOTICE:  dummy_update_func(before) called: action = UPDATE, old = (f), new = (t)
 NOTICE:  dummy_update_func(aftera) called: action = UPDATE, old = (f), new = (t)
+ALTER TABLE some_t ENABLE REPLICA TRIGGER some_trig_aftera;
+ALTER TABLE some_t DISABLE TRIGGER some_trig_afterb;
+ALTER TABLE some_t ENABLE ALWAYS TRIGGER some_trig_before;
 CREATE TABLE some_t1 (c INT, LIKE some_t INCLUDING TRIGGERS INCLUDING COMMENTS);
 \d+ some_t1
                                    Table "public.some_t1"
@@ -485,10 +488,12 @@ CREATE TABLE some_t1 (c INT, LIKE some_t INCLUDING TRIGGERS INCLUDING COMMENTS);
  some_col | boolean |           | not null |         | plain   |              | 
 Not-null constraints:
     "some_t_some_col_not_null" NOT NULL "some_col"
-Triggers:
-    some_trig_aftera AFTER UPDATE ON some_t1 FOR EACH ROW WHEN (NOT old.some_col AND new.some_col) EXECUTE FUNCTION dummy_update_func('aftera')
+Disabled user triggers:
     some_trig_afterb AFTER UPDATE ON some_t1 FOR EACH ROW WHEN (NOT new.some_col) EXECUTE FUNCTION dummy_update_func('afterb')
+Triggers firing always:
     some_trig_before BEFORE UPDATE ON some_t1 FOR EACH ROW EXECUTE FUNCTION dummy_update_func('before')
+Triggers firing on replica only:
+    some_trig_aftera AFTER UPDATE ON some_t1 FOR EACH ROW WHEN (NOT old.some_col AND new.some_col) EXECUTE FUNCTION dummy_update_func('aftera')
 
 DROP TABLE some_t;
 DROP TABLE some_t1;
diff --git a/src/test/regress/sql/triggers.sql b/src/test/regress/sql/triggers.sql
index 19ef0353cb8..154d9b22aca 100644
--- a/src/test/regress/sql/triggers.sql
+++ b/src/test/regress/sql/triggers.sql
@@ -286,6 +286,9 @@ INSERT INTO some_t VALUES (TRUE);
 UPDATE some_t SET some_col = TRUE;
 UPDATE some_t SET some_col = FALSE;
 UPDATE some_t SET some_col = TRUE;
+ALTER TABLE some_t ENABLE REPLICA TRIGGER some_trig_aftera;
+ALTER TABLE some_t DISABLE TRIGGER some_trig_afterb;
+ALTER TABLE some_t ENABLE ALWAYS TRIGGER some_trig_before;
 CREATE TABLE some_t1 (c INT, LIKE some_t INCLUDING TRIGGERS INCLUDING COMMENTS);
 \d+ some_t1
 DROP TABLE some_t;
-- 
2.34.1

