From 0f08984a215f180423e6c5d3899d3c3b6b65024e Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Mon, 2 Mar 2026 10:35:26 +0800
Subject: [PATCH v10 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 6aaaf738662..576f4d2d00f 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -2041,6 +2041,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 09654aba5f0..c74dd98b342 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -14090,6 +14090,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;
@@ -14151,6 +14152,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;
@@ -14213,6 +14215,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;
@@ -21206,6 +21209,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 f55a08f0088..ab085bf1f41 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7096,6 +7096,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 6fca2636116..e0dfce69259 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -6196,6 +6196,7 @@ CreateTrigStmt:
 					CreateTrigStmt *n = makeNode(CreateTrigStmt);
 
 					n->replace = $2;
+					n->tgenabled = TRIGGER_FIRES_ON_ORIGIN;
 					n->isconstraint = false;
 					n->trigname = $4;
 					n->relation = $8;
@@ -6247,6 +6248,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 73a56f1df1d..f708df57ee3 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1705,10 +1705,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 a7d01f5f9fd..c53d9d6bd3e 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -3217,6 +3217,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 f675786739d..2e9c352a690 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 1afaeb863f7..9fb16c72323 100644
--- a/src/test/regress/sql/triggers.sql
+++ b/src/test/regress/sql/triggers.sql
@@ -288,6 +288,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

