report_create_opfamily_event_on_opclass_creation.patch

application/octet-stream

Filename: report_create_opfamily_event_on_opclass_creation.patch
Type: application/octet-stream
Part: 0
Message: Re: Implicitly created operator family not listed by pg_event_trigger_ddl_commands

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
src/backend/commands/opclasscmds.c 13 3
src/backend/tcop/utility.c 6 0
src/test/modules/test_ddl_deparse/expected/opfamily.out 1 0
src/test/regress/expected/event_trigger.out 5 0
src/test/regress/sql/event_trigger.sql 4 0
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 66987966b4..107b707e6e 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 *amname, const char *opfname,
+			   Oid namespaceoid, Oid amoid)
 {
 	Oid			opfamilyoid;
 	Relation	rel;
@@ -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,12 +452,17 @@ DefineOpClass(CreateOpClassStmt *stmt)
 		}
 		else
 		{
+			CreateOpFamilyStmt opfstmt;
 			ObjectAddress tmpAddr;
 
+			opfstmt.type = T_CreateOpFamilyStmt;
+			opfstmt.opfamilyname = stmt->opclassname;
+			opfstmt.amname = stmt->amname;
+
 			/*
 			 * Create it ... again no need for more permissions ...
 			 */
-			tmpAddr = CreateOpFamily(stmt->amname, opcname,
+			tmpAddr = CreateOpFamily(&opfstmt, stmt->amname, opcname,
 									 namespaceoid, amoid);
 			opfamilyoid = tmpAddr.objectId;
 		}
@@ -792,7 +802,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, stmt->amname, 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..8cc70ae3d7 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={}
+-- CRAETE OPERATOR CLASS without FAMILY clause should report
+-- both CRAETE OPERATOR FAMILY and CRAETE 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..8cfc18cb46 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;
 
+-- CRAETE OPERATOR CLASS without FAMILY clause should report
+-- both CRAETE OPERATOR FAMILY and CRAETE 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;