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:
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user