pg_event_trigger_dropped_objects: add behavior flags
Add "normal" and "original" flags as output columns to the pg_event_trigger_dropped_objects() function. With this it's possible to distinguish which objects, among those listed, need to be explicitely referenced when trying to replicate a deletion. This is necessary so that the list of objects can be pruned to the minimum necessary to replicate the DROP command in a remote server that might have slightly different schema (for instance, TOAST tables and constraints with different names and such.) Catalog version bumped due to change of function definition. Reviewed by: Abhijit Menon-Sen, Stephen Frost, Heikki Linnakangas, Robert Haas.
This commit is contained in:
parent
5c805d0a81
commit
0ee98d1cbf
@ -17729,6 +17729,19 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
|
||||
<entry><type>int32</type></entry>
|
||||
<entry>Object sub-id (e.g. attribute number for columns)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>original</literal></entry>
|
||||
<entry><type>bool</type></entry>
|
||||
<entry>Flag used to identify the root object(s) of the deletion</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>normal</literal></entry>
|
||||
<entry><type>bool</type></entry>
|
||||
<entry>
|
||||
Flag indicating that there's a normal dependency relationship
|
||||
in the dependency graph leading to this object
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>object_type</literal></entry>
|
||||
<entry><type>text</type></entry>
|
||||
|
@ -206,16 +206,25 @@ deleteObjectsInList(ObjectAddresses *targetObjects, Relation *depRel,
|
||||
/*
|
||||
* Keep track of objects for event triggers, if necessary.
|
||||
*/
|
||||
if (trackDroppedObjectsNeeded())
|
||||
if (trackDroppedObjectsNeeded() && !(flags & PERFORM_DELETION_INTERNAL))
|
||||
{
|
||||
for (i = 0; i < targetObjects->numrefs; i++)
|
||||
{
|
||||
ObjectAddress *thisobj = targetObjects->refs + i;
|
||||
const ObjectAddress *thisobj = &targetObjects->refs[i];
|
||||
const ObjectAddressExtra *extra = &targetObjects->extras[i];
|
||||
bool original = false;
|
||||
bool normal = false;
|
||||
|
||||
if ((!(flags & PERFORM_DELETION_INTERNAL)) &&
|
||||
EventTriggerSupportsObjectClass(getObjectClass(thisobj)))
|
||||
if (extra->flags & DEPFLAG_ORIGINAL)
|
||||
original = true;
|
||||
if (extra->flags & DEPFLAG_NORMAL)
|
||||
normal = true;
|
||||
if (extra->flags & DEPFLAG_REVERSE)
|
||||
normal = true;
|
||||
|
||||
if (EventTriggerSupportsObjectClass(getObjectClass(thisobj)))
|
||||
{
|
||||
EventTriggerSQLDropAddObject(thisobj);
|
||||
EventTriggerSQLDropAddObject(thisobj, original, normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +117,8 @@ typedef struct SQLDropObject
|
||||
const char *objname;
|
||||
const char *objidentity;
|
||||
const char *objecttype;
|
||||
bool original;
|
||||
bool normal;
|
||||
slist_node next;
|
||||
} SQLDropObject;
|
||||
|
||||
@ -1238,7 +1240,7 @@ trackDroppedObjectsNeeded(void)
|
||||
* Register one object as being dropped by the current command.
|
||||
*/
|
||||
void
|
||||
EventTriggerSQLDropAddObject(ObjectAddress *object)
|
||||
EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool normal)
|
||||
{
|
||||
SQLDropObject *obj;
|
||||
MemoryContext oldcxt;
|
||||
@ -1257,6 +1259,8 @@ EventTriggerSQLDropAddObject(ObjectAddress *object)
|
||||
|
||||
obj = palloc0(sizeof(SQLDropObject));
|
||||
obj->address = *object;
|
||||
obj->original = original;
|
||||
obj->normal = normal;
|
||||
|
||||
/*
|
||||
* Obtain schema names from the object's catalog tuple, if one exists;
|
||||
@ -1384,8 +1388,8 @@ pg_event_trigger_dropped_objects(PG_FUNCTION_ARGS)
|
||||
{
|
||||
SQLDropObject *obj;
|
||||
int i = 0;
|
||||
Datum values[7];
|
||||
bool nulls[7];
|
||||
Datum values[9];
|
||||
bool nulls[9];
|
||||
|
||||
obj = slist_container(SQLDropObject, next, iter.cur);
|
||||
|
||||
@ -1401,6 +1405,12 @@ pg_event_trigger_dropped_objects(PG_FUNCTION_ARGS)
|
||||
/* objsubid */
|
||||
values[i++] = Int32GetDatum(obj->address.objectSubId);
|
||||
|
||||
/* original */
|
||||
values[i++] = BoolGetDatum(obj->original);
|
||||
|
||||
/* normal */
|
||||
values[i++] = BoolGetDatum(obj->normal);
|
||||
|
||||
/* object_type */
|
||||
values[i++] = CStringGetTextDatum(obj->objecttype);
|
||||
|
||||
|
@ -53,6 +53,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 201412122
|
||||
#define CATALOG_VERSION_NO 201412191
|
||||
|
||||
#endif
|
||||
|
@ -5075,7 +5075,7 @@ DATA(insert OID = 3785 ( pg_logical_slot_peek_binary_changes PGNSP PGUID 12 100
|
||||
DESCR("peek at binary changes from replication slot");
|
||||
|
||||
/* event triggers */
|
||||
DATA(insert OID = 3566 ( pg_event_trigger_dropped_objects PGNSP PGUID 12 10 100 0 0 f f f f t t s 0 0 2249 "" "{26,26,23,25,25,25,25}" "{o,o,o,o,o,o,o}" "{classid, objid, objsubid, object_type, schema_name, object_name, object_identity}" _null_ pg_event_trigger_dropped_objects _null_ _null_ _null_ ));
|
||||
DATA(insert OID = 3566 ( pg_event_trigger_dropped_objects PGNSP PGUID 12 10 100 0 0 f f f f t t s 0 0 2249 "" "{26,26,23,16,16,25,25,25,25}" "{o,o,o,o,o,o,o,o,o}" "{classid, objid, objsubid, original, normal, object_type, schema_name, object_name, object_identity}" _null_ pg_event_trigger_dropped_objects _null_ _null_ _null_ ));
|
||||
DESCR("list objects dropped by the current command");
|
||||
DATA(insert OID = 4566 ( pg_event_trigger_table_rewrite_oid PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 26 "" "{26}" "{o}" "{oid}" _null_ pg_event_trigger_table_rewrite_oid _null_ _null_ _null_ ));
|
||||
DESCR("return Oid of the table getting rewritten");
|
||||
|
@ -56,6 +56,7 @@ extern void EventTriggerTableRewrite(Node *parsetree, Oid tableOid, int reason);
|
||||
extern bool EventTriggerBeginCompleteQuery(void);
|
||||
extern void EventTriggerEndCompleteQuery(void);
|
||||
extern bool trackDroppedObjectsNeeded(void);
|
||||
extern void EventTriggerSQLDropAddObject(ObjectAddress *object);
|
||||
extern void EventTriggerSQLDropAddObject(const ObjectAddress *object,
|
||||
bool original, bool normal);
|
||||
|
||||
#endif /* EVENT_TRIGGER_H */
|
||||
|
@ -294,6 +294,46 @@ SELECT * FROM dropped_objects WHERE type = 'schema';
|
||||
DROP ROLE regression_bob;
|
||||
DROP EVENT TRIGGER regress_event_trigger_drop_objects;
|
||||
DROP EVENT TRIGGER undroppable;
|
||||
CREATE OR REPLACE FUNCTION event_trigger_report_dropped()
|
||||
RETURNS event_trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
DECLARE r record;
|
||||
BEGIN
|
||||
FOR r IN SELECT * from pg_event_trigger_dropped_objects()
|
||||
LOOP
|
||||
IF NOT r.normal AND NOT r.original THEN
|
||||
CONTINUE;
|
||||
END IF;
|
||||
RAISE NOTICE 'NORMAL: orig=% normal=% type=% identity=%',
|
||||
r.original, r.normal, r.object_type, r.object_identity;
|
||||
END LOOP;
|
||||
END; $$;
|
||||
CREATE EVENT TRIGGER regress_event_trigger_report_dropped ON sql_drop
|
||||
EXECUTE PROCEDURE event_trigger_report_dropped();
|
||||
CREATE SCHEMA evttrig
|
||||
CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two')
|
||||
CREATE INDEX one_idx ON one (col_b)
|
||||
CREATE TABLE two (col_c INTEGER CHECK (col_c > 0) REFERENCES one DEFAULT 42);
|
||||
ALTER TABLE evttrig.two DROP COLUMN col_c;
|
||||
NOTICE: NORMAL: orig=t normal=f type=table column identity=evttrig.two.col_c
|
||||
NOTICE: NORMAL: orig=f normal=t type=table constraint identity=two_col_c_check on evttrig.two
|
||||
ALTER TABLE evttrig.one ALTER COLUMN col_b DROP DEFAULT;
|
||||
NOTICE: NORMAL: orig=t normal=f type=default value identity=for evttrig.one.col_b
|
||||
ALTER TABLE evttrig.one DROP CONSTRAINT one_pkey;
|
||||
NOTICE: NORMAL: orig=t normal=f type=table constraint identity=one_pkey on evttrig.one
|
||||
DROP INDEX evttrig.one_idx;
|
||||
NOTICE: NORMAL: orig=t normal=f type=index identity=evttrig.one_idx
|
||||
DROP SCHEMA evttrig CASCADE;
|
||||
NOTICE: drop cascades to 2 other objects
|
||||
DETAIL: drop cascades to table evttrig.one
|
||||
drop cascades to table evttrig.two
|
||||
NOTICE: NORMAL: orig=t normal=f type=schema identity=evttrig
|
||||
NOTICE: NORMAL: orig=f normal=t type=table identity=evttrig.one
|
||||
NOTICE: NORMAL: orig=f normal=t type=sequence identity=evttrig.one_col_a_seq
|
||||
NOTICE: NORMAL: orig=f normal=t type=default value identity=for evttrig.one.col_a
|
||||
NOTICE: NORMAL: orig=f normal=t type=table identity=evttrig.two
|
||||
DROP EVENT TRIGGER regress_event_trigger_report_dropped;
|
||||
-- only allowed from within an event trigger function, should fail
|
||||
select pg_event_trigger_table_rewrite_oid();
|
||||
ERROR: pg_event_trigger_table_rewrite_oid() can only be called in a table_rewrite event trigger function
|
||||
|
@ -207,6 +207,36 @@ DROP ROLE regression_bob;
|
||||
DROP EVENT TRIGGER regress_event_trigger_drop_objects;
|
||||
DROP EVENT TRIGGER undroppable;
|
||||
|
||||
CREATE OR REPLACE FUNCTION event_trigger_report_dropped()
|
||||
RETURNS event_trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
DECLARE r record;
|
||||
BEGIN
|
||||
FOR r IN SELECT * from pg_event_trigger_dropped_objects()
|
||||
LOOP
|
||||
IF NOT r.normal AND NOT r.original THEN
|
||||
CONTINUE;
|
||||
END IF;
|
||||
RAISE NOTICE 'NORMAL: orig=% normal=% type=% identity=%',
|
||||
r.original, r.normal, r.object_type, r.object_identity;
|
||||
END LOOP;
|
||||
END; $$;
|
||||
CREATE EVENT TRIGGER regress_event_trigger_report_dropped ON sql_drop
|
||||
EXECUTE PROCEDURE event_trigger_report_dropped();
|
||||
CREATE SCHEMA evttrig
|
||||
CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two')
|
||||
CREATE INDEX one_idx ON one (col_b)
|
||||
CREATE TABLE two (col_c INTEGER CHECK (col_c > 0) REFERENCES one DEFAULT 42);
|
||||
|
||||
ALTER TABLE evttrig.two DROP COLUMN col_c;
|
||||
ALTER TABLE evttrig.one ALTER COLUMN col_b DROP DEFAULT;
|
||||
ALTER TABLE evttrig.one DROP CONSTRAINT one_pkey;
|
||||
DROP INDEX evttrig.one_idx;
|
||||
DROP SCHEMA evttrig CASCADE;
|
||||
|
||||
DROP EVENT TRIGGER regress_event_trigger_report_dropped;
|
||||
|
||||
-- only allowed from within an event trigger function, should fail
|
||||
select pg_event_trigger_table_rewrite_oid();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user