From d1348ac06049a5dec1480734433bd425d3d622d6 Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Fri, 20 May 2022 12:33:43 +0200
Subject: [PATCH] Fix CREATE OPERATOR CLASS deparsing

---
 src/backend/commands/opclasscmds.c            | 19 ++++++++++++++-----
 src/backend/tcop/utility.c                    |  6 ++++++
 .../test_ddl_deparse/expected/opfamily.out    |  1 +
 src/test/regress/expected/event_trigger.out   |  5 +++++
 src/test/regress/sql/event_trigger.sql        |  4 ++++
 5 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 66987966b4..7a931ab758 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -240,7 +240,8 @@ get_opclass_oid(Oid amID, List *opclassname, bool missing_ok)
  * Caller must have done permissions checks etc. already.
  */
 static ObjectAddress
-CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid amoid)
+CreateOpFamily(CreateOpFamilyStmt *stmt, const char *opfname,
+			   Oid namespaceoid, Oid amoid)
 {
 	Oid			opfamilyoid;
 	Relation	rel;
@@ -264,7 +265,7 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am
 		ereport(ERROR,
 				(errcode(ERRCODE_DUPLICATE_OBJECT),
 				 errmsg("operator family \"%s\" for access method \"%s\" already exists",
-						opfname, amname)));
+						opfname, stmt->amname)));
 
 	/*
 	 * Okay, let's create the pg_opfamily entry.
@@ -312,6 +313,10 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am
 	/* dependency on extension */
 	recordDependencyOnCurrentExtension(&myself, false);
 
+	/* Report the new operator family to possibly interested event triggers */
+	EventTriggerCollectSimpleCommand(myself, InvalidObjectAddress,
+									 (Node *) stmt);
+
 	/* Post creation hook for new operator family */
 	InvokeObjectPostCreateHook(OperatorFamilyRelationId, opfamilyoid, 0);
 
@@ -447,13 +452,17 @@ DefineOpClass(CreateOpClassStmt *stmt)
 		}
 		else
 		{
+			CreateOpFamilyStmt *opfstmt;
 			ObjectAddress tmpAddr;
 
+			opfstmt = makeNode(CreateOpFamilyStmt);
+			opfstmt->opfamilyname = stmt->opclassname;
+			opfstmt->amname = stmt->amname;
+
 			/*
 			 * Create it ... again no need for more permissions ...
 			 */
-			tmpAddr = CreateOpFamily(stmt->amname, opcname,
-									 namespaceoid, amoid);
+			tmpAddr = CreateOpFamily(opfstmt, opcname, namespaceoid, amoid);
 			opfamilyoid = tmpAddr.objectId;
 		}
 	}
@@ -792,7 +801,7 @@ DefineOpFamily(CreateOpFamilyStmt *stmt)
 				 errmsg("must be superuser to create an operator family")));
 
 	/* Insert pg_opfamily catalog entry */
-	return CreateOpFamily(stmt->amname, opfname, namespaceoid, amoid);
+	return CreateOpFamily(stmt, opfname, namespaceoid, amoid);
 }
 
 
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 0e7b7b3138..6a5bcded55 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1721,6 +1721,12 @@ ProcessUtilitySlow(ParseState *pstate,
 
 			case T_CreateOpFamilyStmt:
 				address = DefineOpFamily((CreateOpFamilyStmt *) parsetree);
+
+				/*
+				 * DefineOpFamily calls EventTriggerCollectSimpleCommand
+				 * directly.
+				 */
+				commandCollected = true;
 				break;
 
 			case T_CreateTransformStmt:
diff --git a/src/test/modules/test_ddl_deparse/expected/opfamily.out b/src/test/modules/test_ddl_deparse/expected/opfamily.out
index 14bd6037cd..c7e3a23ef7 100644
--- a/src/test/modules/test_ddl_deparse/expected/opfamily.out
+++ b/src/test/modules/test_ddl_deparse/expected/opfamily.out
@@ -64,4 +64,5 @@ NOTICE:  DDL test: type simple, tag CREATE OPERATOR
 create operator class ctype_hash_ops
   default for type ctype using hash as
   operator 1 =(ctype, ctype);
+NOTICE:  DDL test: type simple, tag CREATE OPERATOR FAMILY
 NOTICE:  DDL test: type create operator class, tag CREATE OPERATOR CLASS
diff --git a/src/test/regress/expected/event_trigger.out b/src/test/regress/expected/event_trigger.out
index 44d545de25..c95c30b314 100644
--- a/src/test/regress/expected/event_trigger.out
+++ b/src/test/regress/expected/event_trigger.out
@@ -476,6 +476,11 @@ NOTICE:  NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.part_10_15
 NOTICE:  NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.part_15_20 name={evttrig,part_15_20} args={}
 DROP TABLE a_temp_tbl;
 NOTICE:  NORMAL: orig=t normal=f istemp=t type=table identity=pg_temp.a_temp_tbl name={pg_temp,a_temp_tbl} args={}
+-- CREATE OPERATOR CLASS without FAMILY clause should report
+-- both CREATE OPERATOR FAMILY and CREATE OPERATOR CLASS
+CREATE OPERATOR CLASS evttrigopclass FOR TYPE int USING btree AS STORAGE int;
+NOTICE:  END: command_tag=CREATE OPERATOR FAMILY type=operator family identity=public.evttrigopclass USING btree
+NOTICE:  END: command_tag=CREATE OPERATOR CLASS type=operator class identity=public.evttrigopclass USING btree
 DROP EVENT TRIGGER regress_event_trigger_report_dropped;
 DROP EVENT TRIGGER regress_event_trigger_report_end;
 -- only allowed from within an event trigger function, should fail
diff --git a/src/test/regress/sql/event_trigger.sql b/src/test/regress/sql/event_trigger.sql
index 1446cf8cc8..5e45e3f190 100644
--- a/src/test/regress/sql/event_trigger.sql
+++ b/src/test/regress/sql/event_trigger.sql
@@ -337,6 +337,10 @@ DROP INDEX evttrig.one_idx;
 DROP SCHEMA evttrig CASCADE;
 DROP TABLE a_temp_tbl;
 
+-- CREATE OPERATOR CLASS without FAMILY clause should report
+-- both CREATE OPERATOR FAMILY and CREATE OPERATOR CLASS
+CREATE OPERATOR CLASS evttrigopclass FOR TYPE int USING btree AS STORAGE int;
+
 DROP EVENT TRIGGER regress_event_trigger_report_dropped;
 DROP EVENT TRIGGER regress_event_trigger_report_end;
 
-- 
2.30.2

