1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-04 20:11:56 +03:00

Fix oversights in pg_event_trigger_dropped_objects() fixes.

Commit a0b99fc12 caused pg_event_trigger_dropped_objects()
to not fill the object_name field for schemas, which it
should have; and caused it to fill the object_name field
for default values, which it should not have.

In addition, triggers and RLS policies really should behave
the same way as we're making column defaults do; that is,
they should have is_temporary = true if they belong to a
temporary table.

Fix those things, and upgrade event_trigger.sql's woefully
inadequate test coverage of these secondary output columns.

As before, back-patch only to v15.

Reported-by: Sergey Shinderuk <s.shinderuk@postgrespro.ru>
Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/bd7b4651-1c26-4d30-832b-f942fabcb145@postgrespro.ru
Backpatch-through: 15
This commit is contained in:
Tom Lane
2025-09-12 17:43:15 -04:00
parent 451373dc5c
commit 33e49ee014
3 changed files with 243 additions and 84 deletions

View File

@@ -13,6 +13,7 @@
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/table.h"
#include "access/xact.h"
@@ -25,6 +26,7 @@
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_policy.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_ts_config.h"
@@ -1202,6 +1204,7 @@ EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool no
MemoryContextSwitchTo(oldcxt);
return;
}
obj->objname = get_namespace_name(object->objectId);
}
else if (object->classId == AttrDefaultRelationId)
{
@@ -1211,7 +1214,6 @@ EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool no
colobject = GetAttrDefaultColumnAddress(object->objectId);
if (OidIsValid(colobject.objectId))
{
colobject.objectSubId = 0; /* convert to table reference */
if (!obtain_object_name_namespace(&colobject, obj))
{
pfree(obj);
@@ -1220,6 +1222,90 @@ EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool no
}
}
}
else if (object->classId == TriggerRelationId)
{
/* Similarly, a trigger is temp if its table is temp */
/* Sadly, there's no lsyscache.c support for trigger objects */
Relation pg_trigger_rel;
ScanKeyData skey[1];
SysScanDesc sscan;
HeapTuple tuple;
Oid relid;
/* Fetch the trigger's table OID the hard way */
pg_trigger_rel = table_open(TriggerRelationId, AccessShareLock);
ScanKeyInit(&skey[0],
Anum_pg_trigger_oid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(object->objectId));
sscan = systable_beginscan(pg_trigger_rel, TriggerOidIndexId, true,
NULL, 1, skey);
tuple = systable_getnext(sscan);
if (HeapTupleIsValid(tuple))
relid = ((Form_pg_trigger) GETSTRUCT(tuple))->tgrelid;
else
relid = InvalidOid; /* shouldn't happen */
systable_endscan(sscan);
table_close(pg_trigger_rel, AccessShareLock);
/* Do nothing if we didn't find the trigger */
if (OidIsValid(relid))
{
ObjectAddress relobject;
relobject.classId = RelationRelationId;
relobject.objectId = relid;
/* Arbitrarily set objectSubId nonzero so as not to fill objname */
relobject.objectSubId = 1;
if (!obtain_object_name_namespace(&relobject, obj))
{
pfree(obj);
MemoryContextSwitchTo(oldcxt);
return;
}
}
}
else if (object->classId == PolicyRelationId)
{
/* Similarly, a policy is temp if its table is temp */
/* Sadly, there's no lsyscache.c support for policy objects */
Relation pg_policy_rel;
ScanKeyData skey[1];
SysScanDesc sscan;
HeapTuple tuple;
Oid relid;
/* Fetch the policy's table OID the hard way */
pg_policy_rel = table_open(PolicyRelationId, AccessShareLock);
ScanKeyInit(&skey[0],
Anum_pg_policy_oid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(object->objectId));
sscan = systable_beginscan(pg_policy_rel, PolicyOidIndexId, true,
NULL, 1, skey);
tuple = systable_getnext(sscan);
if (HeapTupleIsValid(tuple))
relid = ((Form_pg_policy) GETSTRUCT(tuple))->polrelid;
else
relid = InvalidOid; /* shouldn't happen */
systable_endscan(sscan);
table_close(pg_policy_rel, AccessShareLock);
/* Do nothing if we didn't find the policy */
if (OidIsValid(relid))
{
ObjectAddress relobject;
relobject.classId = RelationRelationId;
relobject.objectId = relid;
/* Arbitrarily set objectSubId nonzero so as not to fill objname */
relobject.objectSubId = 1;
if (!obtain_object_name_namespace(&relobject, obj))
{
pfree(obj);
MemoryContextSwitchTo(oldcxt);
return;
}
}
}
else
{
/* Generic handling for all other object classes */