BUG #17607: Server process crashes when PLpgSQL function raises error in subtransaction - Mailing list pgsql-bugs
From | PG Bug reporting form |
---|---|
Subject | BUG #17607: Server process crashes when PLpgSQL function raises error in subtransaction |
Date | |
Msg-id | 17607-bd8ccc81226f7f80@postgresql.org Whole thread Raw |
Responses |
Re: BUG #17607: Server process crashes when PLpgSQL function raises error in subtransaction
|
List | pgsql-bugs |
The following bug has been logged on the website: Bug reference: 17607 Logged by: Thomas Mc Kay Email address: thomas.d.mckay@gmail.com PostgreSQL version: 13.8 Operating system: Debian in docker Description: Hello, I've encountered a bug while doing some SQL migrations on a PostgreSQL 13.8 server. My initial use-case is a Django app running migrations, a test setup and a test, but that code was more than 10K lines of DDL, so I've reduced the code to a minimal reproducible example (as best I could). I also tested the same script in 14.0 and 14.5 and in both, the bug is fixed. I haven't seen anything related to it in the changelog for 14.0, so I don't know whether the bug was fixed purposefully and forgotten in the changelog or if it was fixed by accident, maybe as a corollary of another bugfix/feature. I also don't know if this is something the devs would want to fix in the 13.x line. Either way, I figured it might make a good regression test case for 14.x. Environment (Docker): - PostgreSQL 13.8 (Debian 13.8-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit Test code: ``` -- Migration 1 CREATE TABLE "tbl" ("id" serial NOT NULL PRIMARY KEY); -- Migration 2 ALTER TABLE "tbl" ADD COLUMN "value" int DEFAULT 0 NOT NULL; CREATE FUNCTION on_tbl_parent_id_change_fn() RETURNS TRIGGER AS $on_tbl_parent_id_change$ BEGIN RAISE EXCEPTION 'BOOM !'; END $on_tbl_parent_id_change$ LANGUAGE PLpgSQL VOLATILE; CREATE TRIGGER on_tbl_parent_id_update AFTER UPDATE ON tbl REFERENCING OLD TABLE AS old_rows NEW TABLE AS new_rows FOR EACH STATEMENT EXECUTE PROCEDURE on_tbl_parent_id_change_fn(); -- Test setup INSERT INTO "tbl" ("value") VALUES (2); -- Test BEGIN; SAVEPOINT svp; UPDATE tbl SET value=1; -- Fails here ROLLBACK TO SAVEPOINT svp; ROLLBACK; ``` Output (verbose): ``` -- CREATE TABLE -- ALTER TABLE -- CREATE FUNCTION -- CREATE TRIGGER -- INSERT 0 1 -- BEGIN -- SAVEPOINT -- WARNING: 01000: AbortSubTransaction while in ABORT state -- LOCATION: AbortSubTransaction, xact.c:4999 -- WARNING: 01000: AbortSubTransaction while in ABORT state -- LOCATION: AbortSubTransaction, xact.c:4999 -- WARNING: 01000: AbortSubTransaction while in ABORT state -- LOCATION: AbortSubTransaction, xact.c:4999 -- ERROR: P0001: BOOM ! -- CONTEXT: PL/pgSQL function on_tbl_parent_id_change_fn() line 3 at RAISE -- LOCATION: exec_stmt_raise, pl_exec.c:3854 -- ERROR: XX000: tupdesc reference 0x7fc02873fbc8 is not owned by resource owner SubTransaction -- LOCATION: ResourceOwnerForgetTupleDesc, resowner.c:1188 -- ERROR: XX000: tupdesc reference 0x7fc02873fbc8 is not owned by resource owner SubTransaction -- LOCATION: ResourceOwnerForgetTupleDesc, resowner.c:1188 -- ERROR: XX000: tupdesc reference 0x7fc02873fbc8 is not owned by resource owner SubTransaction -- LOCATION: ResourceOwnerForgetTupleDesc, resowner.c:1188 -- ERROR: XX000: tupdesc reference 0x7fc02873fbc8 is not owned by resource owner SubTransaction -- LOCATION: ResourceOwnerForgetTupleDesc, resowner.c:1188 -- PANIC: XX000: ERRORDATA_STACK_SIZE exceeded -- LOCATION: errstart, elog.c:359 -- server closed the connection unexpectedly -- This probably means the server terminated abnormally -- before or while processing the request. -- The connection to the server was lost. Attempting reset: Failed. -- You are currently not connected to a database. -- You are currently not connected to a database. ``` Expected output: ``` CREATE TABLE ALTER TABLE CREATE FUNCTION CREATE TRIGGER INSERT 0 1 BEGIN SAVEPOINT ERROR: BOOM ! CONTEXT: PL/pgSQL function on_tbl_parent_id_change_fn() line 3 at RAISE ROLLBACK ROLLBACK ``` The bug disappears if any of the following is true: - value is added to the table definition and not with ALTER TABLE. - value is declared without a default. - `REFERENCING OLD TABLE AS old_rows NEW TABLE AS new_rows` is removed from the trigger. - a `VACUUM FULL tbl` is done between the trigger creation and the insert. I don't know what to make of it, though. Cheers, Thomas
pgsql-bugs by date:
Previous
From: Dmitriy KuzminDate:
Subject: Startup process on a hot standby crashes with an error "invalid memory alloc request size 1073741824" while replaying "Standby/LOCK" records
Next
From: David RowleyDate:
Subject: Re: Startup process on a hot standby crashes with an error "invalid memory alloc request size 1073741824" while replaying "Standby/LOCK" records