mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	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