Hi all, This SQL crashes assert-enabled builds:
CREATE TABLE t(a int);
CREATE FUNCTION f() RETURNS trigger LANGUAGE plpgsql AS $$
BEGIN
BEGIN
PERFORM 1 / 0;
EXCEPTION WHEN division_by_zero THEN
NULL;
END;
RETURN NEW;
END
$$;
CREATE CONSTRAINT TRIGGER trg
AFTER INSERT ON t
DEFERRABLE INITIALLY DEFERRED
FOR EACH ROW EXECUTE FUNCTION f();
BEGIN;
INSERT INTO t VALUES (1);
COMMIT; -- backend aborts here on assert builds
The failure in the logs is:
TRAP: failed Assert("s->blockState == TBLOCK_SUBINPROGRESS || s->blockState
== TBLOCK_INPROGRESS || s->blockState == TBLOCK_IMPLICIT_INPROGRESS ||
s->blockState == TBLOCK_PARALLEL_INPROGRESS || s->blockState ==
TBLOCK_STARTED"), File: "xact.c", Line: 4851, PID: 73455
0 postgres 0x0000000104e6b330 ExceptionalCondition + 108
1 postgres 0x0000000104a33620 AbortSubTransaction + 0
2 plpgsql.dylib 0x00000001056b14b8 exec_stmt_block + 640
3 plpgsql.dylib 0x00000001056b1d00 exec_stmts + 188
`PREPARE TRANSACTION 'tx'` in place of the final `COMMIT` crashes in the
same way.
fa0e318 updated BeginInternalSubTransaction to allow creating a
subtransaction with a parent of TBLOCK_END and TBLOCK_PREPARE but didn't
add those states to the assert in RollbackAndReleaseCurrentSubTransaction.
The `division_by_zero` exception in the example forces a subtransaction to
abort in the context of the final `COMMIT`, so
RollbackAndReleaseCurrentSubTransaction needs to allow TBLOCK_PREPARE and
TBLOCK_END.
Check the attached patch for the fix.
Regards,
--
FabrÃzio Mello
PlanetScale Postgres Core Team
v1-0001-Fix-failing-assert-in-deferred-constraint-trigger.patch
Description: Binary data
