]> granicus.if.org Git - postgresql/commitdiff
pg_event_trigger_dropped_objects: add behavior flags
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 19 Dec 2014 18:00:45 +0000 (15:00 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 19 Dec 2014 18:00:45 +0000 (15:00 -0300)
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.

doc/src/sgml/func.sgml
src/backend/catalog/dependency.c
src/backend/commands/event_trigger.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h
src/include/commands/event_trigger.h
src/test/regress/expected/event_trigger.out
src/test/regress/sql/event_trigger.sql

index 7934a1263e1a948052e73b3d6539a39bab96e3d1..6f3094656c2107b2c179d27fa8a843edb906721c 100644 (file)
@@ -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>
index 8ba5123c101a51e0dde74a49971477c2640932de..3027259a3aa6bac30b665145f00b170d7eb83574 100644 (file)
@@ -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;
-
-                       if ((!(flags & PERFORM_DELETION_INTERNAL)) &&
-                               EventTriggerSupportsObjectClass(getObjectClass(thisobj)))
+                       const ObjectAddress *thisobj = &targetObjects->refs[i];
+                       const ObjectAddressExtra *extra = &targetObjects->extras[i];
+                       bool    original = false;
+                       bool    normal = false;
+
+                       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);
                        }
                }
        }
index 6fb4817845cde341a0b3f29ec289e251b4c52c20..8b88ecb359e196d8f54174394849e382be89d1f8 100644 (file)
@@ -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);
 
index bedab8b658b2713b81e73098b18e4e3458ffec60..5e9961af69d43b0d0aee612c00f3966eaf395d74 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     201412122
+#define CATALOG_VERSION_NO     201412191
 
 #endif
index eace352ec0fdbf46f2bfc3ffcb38a89afb77867f..f766ed791fb46199f53dc93de898acb64e3ecbf9 100644 (file)
@@ -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");
index bcd656b72dd146c95d334280a8636a100c4d20e6..b402547739d832c9b013b13c01d9aba0ac202ba2 100644 (file)
@@ -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 */
index 5934cf74b197ecb7ef36c4be8789baad2bb47fd5..72e1660d6b9e5e419e186b0b21523e8816ce0b1b 100644 (file)
@@ -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
index 02b93c9e1f09a3f7187fd1aa23f28c79e76ac274..7987fde50b9f293f06cfd667e64cc98c4a01319d 100644 (file)
@@ -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();