On Mon, 30 Mar 2026 10:16:02 +0900 Amit Langote <[email protected]> wrote:
> On Fri, Mar 27, 2026 at 2:36 PM Amit Langote <[email protected]> wrote: > > On Fri, Mar 27, 2026 at 12:01 PM Yugo Nagata <[email protected]> wrote: > > > On Fri, 27 Mar 2026 09:39:17 +0900 > > > Amit Langote <[email protected]> wrote: > > > > > > > On Fri, Mar 27, 2026 at 12:56 AM Yugo Nagata <[email protected]> > > > > wrote: > > > > > > > > > > Hi, > > > > > > > > > > Thank you all for the review and comments. > > > > > > > > > > > Yes Amit, I agree that SPI_execute_snapshot() comments do provide > > > > > > some > > > > > > context on AFTER triggers, but I still feel the newly added comment > > > > > > in ri_PerformCheck() gives additional context on why the > > > > > > fire_triggers is > > > > > > set to false. > > > > > > > > > > Yes, that is what I intended. The existing comments on > > > > > SPI_execute_snapshot() explain how the fire_triggers parameter works, > > > > > but I would like to add a comment explaining why the AFTER trigger for > > > > > RI needs to set it to false. > > > > > > > > > > If the explanation of the effect of fire_triggers seems redundant, I > > > > > am > > > > > fine with the following shorter version: > > > > > > > > > > + * Set fire_triggers to false to ensure that check triggers > > > > > fire after all > > > > > + * RI updates on the same row are complete. > > > > > > > > Thanks for the updated patch. Yes, adding the comment might be good, > > > > but I'd suggest a small tweak: > > > > > > > > + * Set fire_triggers to false to ensure that AFTER triggers > > > > are queued in > > > > + * the outer query's after-trigger context and fire after all > > > > RI updates on > > > > + * the same row are complete, rather than immediately. > > > > > > > > Two changes: > > > > > > > > * "check triggers" -> "AFTER triggers", since fire_triggers=false > > > > affects any AFTER triggers queued during the SPI execution, not just > > > > RI check triggers. > > > > > > > > * mention of the outer query's after-trigger context to explain the > > > > mechanism by which the deferral works. > > > > > > > > Does that additional context help? > > > > > > Thank you for the suggestion. > > > That looks good to me. It is clearer than the previous version. > > > > Ok, will push the attached. > > Pushed. Thank you! > I verified locally with a test case involving a CASCADE DELETE on two > parent rows that the comment is indeed accurate: > > CREATE TABLE parent (id int PRIMARY KEY); > CREATE TABLE child (id int REFERENCES parent ON DELETE CASCADE); > CREATE TABLE log (seq serial, msg text); > > CREATE OR REPLACE FUNCTION child_after_del() RETURNS trigger AS $$ > BEGIN > INSERT INTO log(msg) VALUES ('child deleted: ' || OLD.id); > RETURN NULL; > END; > $$ LANGUAGE plpgsql; > > CREATE TRIGGER "A_child_after_del_trig" > AFTER DELETE ON child > FOR EACH ROW EXECUTE FUNCTION child_after_del(); > CREATE OR REPLACE FUNCTION parent_after_del() RETURNS trigger AS $$ > BEGIN > INSERT INTO log(msg) VALUES ('parent deleted: ' || OLD.id); > RETURN NULL; > END; > $$ LANGUAGE plpgsql; > > CREATE TRIGGER "A_parent_after_del_trig" > AFTER DELETE ON parent > FOR EACH ROW EXECUTE FUNCTION parent_after_del(); > > INSERT INTO parent VALUES (1), (2); > INSERT INTO child VALUES (1), (2); > DELETE FROM parent; > > SELECT msg FROM log ORDER BY seq; > msg > ------------------- > parent deleted: 1 > parent deleted: 2 > child deleted: 1 > child deleted: 2 > (4 rows) > Thank you for the verification. This behavior seems consistent with the comment. Regards, Yugo Nagata -- Yugo Nagata <[email protected]>
