Fix DDL deparse of CREATE OPERATOR CLASS

When an implicit operator family is created, it wasn't getting reported.
Make it do so.

This has always been missing.  Backpatch to 10.

Author: Masahiko Sawada <sawada.mshk@gmail.com>
Reported-by: Leslie LEMAIRE <leslie.lemaire@developpement-durable.gouv.fr>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Reviewed-by: Michael Paquiër <michael@paquier.xyz>
Discussion: https://postgr.es/m/f74d69e151b22171e8829551b1159e77@developpement-durable.gouv.fr
This commit is contained in:
Alvaro Herrera 2022-05-20 18:52:55 +02:00
parent fa51cc86c6
commit 70f70d7d3f
No known key found for this signature in database
GPG Key ID: 1C20ACB9D5C564AE
5 changed files with 28 additions and 5 deletions

View File

@ -238,7 +238,8 @@ get_opclass_oid(Oid amID, List *opclassname, bool missing_ok)
* Caller must have done permissions checks etc. already. * Caller must have done permissions checks etc. already.
*/ */
static ObjectAddress static ObjectAddress
CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid) CreateOpFamily(CreateOpFamilyStmt *stmt, const char *opfname,
Oid namespaceoid, Oid amoid)
{ {
Oid opfamilyoid; Oid opfamilyoid;
Relation rel; Relation rel;
@ -262,7 +263,7 @@ CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT), (errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("operator family \"%s\" for access method \"%s\" already exists", errmsg("operator family \"%s\" for access method \"%s\" already exists",
opfname, amname))); opfname, stmt->amname)));
/* /*
* Okay, let's create the pg_opfamily entry. * Okay, let's create the pg_opfamily entry.
@ -307,6 +308,10 @@ CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid)
/* dependency on extension */ /* dependency on extension */
recordDependencyOnCurrentExtension(&myself, false); 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 */ /* Post creation hook for new operator family */
InvokeObjectPostCreateHook(OperatorFamilyRelationId, opfamilyoid, 0); InvokeObjectPostCreateHook(OperatorFamilyRelationId, opfamilyoid, 0);
@ -438,13 +443,17 @@ DefineOpClass(CreateOpClassStmt *stmt)
} }
else else
{ {
CreateOpFamilyStmt *opfstmt;
ObjectAddress tmpAddr; ObjectAddress tmpAddr;
opfstmt = makeNode(CreateOpFamilyStmt);
opfstmt->opfamilyname = stmt->opclassname;
opfstmt->amname = stmt->amname;
/* /*
* Create it ... again no need for more permissions ... * Create it ... again no need for more permissions ...
*/ */
tmpAddr = CreateOpFamily(stmt->amname, opcname, tmpAddr = CreateOpFamily(opfstmt, opcname, namespaceoid, amoid);
namespaceoid, amoid);
opfamilyoid = tmpAddr.objectId; opfamilyoid = tmpAddr.objectId;
} }
} }
@ -747,7 +756,7 @@ DefineOpFamily(CreateOpFamilyStmt *stmt)
errmsg("must be superuser to create an operator family"))); errmsg("must be superuser to create an operator family")));
/* Insert pg_opfamily catalog entry */ /* Insert pg_opfamily catalog entry */
return CreateOpFamily(stmt->amname, opfname, namespaceoid, amoid); return CreateOpFamily(stmt, opfname, namespaceoid, amoid);
} }

View File

@ -1558,6 +1558,12 @@ ProcessUtilitySlow(ParseState *pstate,
case T_CreateOpFamilyStmt: case T_CreateOpFamilyStmt:
address = DefineOpFamily((CreateOpFamilyStmt *) parsetree); address = DefineOpFamily((CreateOpFamilyStmt *) parsetree);
/*
* DefineOpFamily calls EventTriggerCollectSimpleCommand
* directly.
*/
commandCollected = true;
break; break;
case T_CreateTransformStmt: case T_CreateTransformStmt:

View File

@ -64,4 +64,5 @@ NOTICE: DDL test: type simple, tag CREATE OPERATOR
create operator class ctype_hash_ops create operator class ctype_hash_ops
default for type ctype using hash as default for type ctype using hash as
operator 1 =(ctype, ctype); operator 1 =(ctype, ctype);
NOTICE: DDL test: type simple, tag CREATE OPERATOR FAMILY
NOTICE: DDL test: type create operator class, tag CREATE OPERATOR CLASS NOTICE: DDL test: type create operator class, tag CREATE OPERATOR CLASS

View File

@ -424,6 +424,9 @@ 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={} 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; 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={} 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;
DROP EVENT TRIGGER regress_event_trigger_report_dropped; DROP EVENT TRIGGER regress_event_trigger_report_dropped;
DROP EVENT TRIGGER regress_event_trigger_report_end; DROP EVENT TRIGGER regress_event_trigger_report_end;
-- only allowed from within an event trigger function, should fail -- only allowed from within an event trigger function, should fail

View File

@ -309,6 +309,10 @@ DROP INDEX evttrig.one_idx;
DROP SCHEMA evttrig CASCADE; DROP SCHEMA evttrig CASCADE;
DROP TABLE a_temp_tbl; 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_dropped;
DROP EVENT TRIGGER regress_event_trigger_report_end; DROP EVENT TRIGGER regress_event_trigger_report_end;