Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deferred Constraint Trigger with Savepoint

Tags:

postgresql

We make use of some deferred constraint triggers in our application and I was hoping to write some tests for them using pgTap. For database tests, we like to wrap things inside of a transaction so that everything is isolated and cleaned up at the end, but this poses a problem for deferred constraint triggers as they don't seem to fire unless the transaction is committed (by design).

Is there any way to get them to fire using savepoints? I attempted something simple like below but it still seems like the deferred trigger won't fire unless I commit the outer transaction.

BEGIN TRANSACTION;

CREATE TABLE test_table_with_trigger
(
    comment text
);

CREATE FUNCTION t_fn_test() RETURNS TRIGGER AS
$$
BEGIN
    RAISE INFO '%', tg_argv;
    RETURN NEW;
END;
$$
    LANGUAGE plpgsql VOLATILE;

CREATE CONSTRAINT TRIGGER t_test_constraint
    AFTER INSERT
    ON test_table_with_trigger DEFERRABLE INITIALLY IMMEDIATE
    FOR EACH ROW
EXECUTE PROCEDURE t_fn_test('constraint trigger');

CREATE TRIGGER t_test
    AFTER INSERT
    ON test_table_with_trigger
    FOR EACH ROW
EXECUTE PROCEDURE t_fn_test('row trigger');

SAVEPOINT nested;

INSERT INTO test_table_with_trigger (comment) VALUES ('will it trigger?');

RELEASE SAVEPOINT nested;

ROLLBACK;
like image 242
Jesse Carter Avatar asked Oct 11 '25 18:10

Jesse Carter


1 Answers

You can issue SET CONSTRAINTS ALL IMMEDIATE right before the end of the transaction, which will lead to the immediate execution of the deferred constraints.

like image 160
Laurenz Albe Avatar answered Oct 15 '25 01:10

Laurenz Albe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!