Statement-level Triggers - Mailing list pgsql-docs
From | PG Doc comments form |
---|---|
Subject | Statement-level Triggers |
Date | |
Msg-id | 154962036706.1294.16337818996776163878@wrigleys.postgresql.org Whole thread Raw |
List | pgsql-docs |
The following documentation comment has been logged on the website: Page: https://www.postgresql.org/docs/11/sql-createtrigger.html Description: The AFTER Statement-level Trigger runs into infinite execution when another set of rows are affected for the same table through this trigger. Consider this use case where a table storage_locations that manages a hierarchy of storage_locations in stores, and thus having following columns (for simplicity): storage_location_id SERIAL NOT NULL PRIMARY KEY, store_id INTEGER NOT NULL, -- REFERENCES stores storage_location_nm VARCHAR (25) NOT NULL, parent_storage_location_id INTEGER NULL REFERENCES storage_locations, ---- NULL for root storage locations storage_location_path TEXT NOT NULL I have a BEFORE ROW trigger, which updates the storage_location_path with parent's storage_location_path, if any, concatenated with its storage_location_name. This works fine - no issues. I have another AFTER UPDATE STATEMENT-level Trigger and function definitions as below (which updates the storage_path of the children): CREATE FUNCTION TRG_storage_locations_b_u_AS_DML () RETURNS TRIGGER AS $$ DECLARE v_separator VARCHAR (1) = '/'; v_cnt INT; BEGIN -- [ -- Required to prevent infinite recursion SELECT COUNT (*) INTO v_cnt FROM new_table; IF (v_cnt > 0) THEN -- ] -- Required to prevent infinite recursion UPDATE storage_locations SET storage_location_path = COALESCE (i.storage_location_path || v_separator, '') || storage_locations.storage_location_nm FROM inserted i JOIN deleted d ON ( i.storage_location_id = d.storage_location_id AND i.storage_location_path != d.storage_location_path ) WHERE storage_locations.parent_storage_location_id = i.storage_location_id; END IF; RETURN NULL; END $$ LANGUAGE plpgsql; CREATE TRIGGER storage_locations_b_u_AS_DML AFTER UPDATE ON storage_locations REFERENCING NEW TABLE AS inserted OLD TABLE AS deleted FOR EACH STATEMENT EXECUTE FUNCTION TRG_storage_locations_b_u_AS_DML (); Notice that the Trigger is getting called endlessly (if the number of rows in the NEW TABLE are NOT checked). I reckon if there are not any rows, what is the need to call the trigger. Or, may be, I am missing something, which I need to learn.
pgsql-docs by date: