From: zengman <zengman@halodbtech.com>
To: 曾满 <zengman@halodbtech.com>
To: pgsql-bugs <pgsql-bugs@lists.postgresql.org>
Subject: Re:BUG #19107: The hold cursor is unexpectedly released during rollback
Date: Mon, 10 Nov 2025 18:50:51 +0800
Message-ID: <tencent_05B43F1B06161796748A12E1@qq.com> (raw)
In-Reply-To: <19107-656a10a7a066f7e9@postgresql.org>
References: <19107-656a10a7a066f7e9@postgresql.org>
If this is indeed a bug, a simple patch is attached to fix this issue.
Attachments:
[application/octet-stream] 001_rollback_no_release_holdcursor.patch (2.8K, ../tencent_05B43F1B06161796748A12E1@qq.com/2-001_rollback_no_release_holdcursor.patch)
download | inline diff:diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.cindex 943da087c9f..15d5fdf448d 100644--- a/src/backend/utils/mmgr/portalmem.c+++ b/src/backend/utils/mmgr/portalmem.c@@ -1238,6 +1238,14 @@ HoldPinnedPortals(void)
HoldPortal(portal);
portal->autoHeld = true;
}
+ else if ((portal->cursorOptions & CURSOR_OPT_HOLD) &&+ portal->createSubid != InvalidSubTransactionId &&+ portal->status == PORTAL_READY)+ {+ /* Is it a holdable portal created in the current xact? */+ HoldPortal(portal);+ portal->autoHeld = true;+ }
}
}
diff --git a/src/pl/plpgsql/src/expected/plpgsql_simple.out b/src/pl/plpgsql/src/expected/plpgsql_simple.outindex da351873e74..3a6342c3abd 100644--- a/src/pl/plpgsql/src/expected/plpgsql_simple.out+++ b/src/pl/plpgsql/src/expected/plpgsql_simple.out@@ -129,3 +129,39 @@ begin
raise notice 'val = %', val;
end; $$;
NOTICE: val = 42
+-- Verify whether the behavior of the hold cursor is consistent during commit and rollback+do $$+declare+ p_CurData refcursor := 'hold_cursor';+ val int;+begin+ execute 'DECLARE hold_cursor CURSOR WITH HOLD FOR SELECT 42';+ loop+ fetch p_CurData into val;+ exit when val is null;+ raise notice 'val = %', val;+ commit;+ end loop;+ close p_CurData;+end; $$;+NOTICE: val = 42+do $$+declare+ p_CurData refcursor := 'hold_cursor';+ val int;+begin+ execute 'DECLARE hold_cursor CURSOR WITH HOLD FOR SELECT 42';+ loop+ fetch p_CurData into val;+ exit when val is null;+ raise notice 'val = %', val;+ rollback;+ end loop;+ close p_CurData;+end; $$;+NOTICE: val = 42+select * from pg_cursors;+ name | statement | is_holdable | is_binary | is_scrollable | creation_time +------+-----------+-------------+-----------+---------------+---------------+(0 rows)+diff --git a/src/pl/plpgsql/src/sql/plpgsql_simple.sql b/src/pl/plpgsql/src/sql/plpgsql_simple.sqlindex 72d8afe4500..898721ea97b 100644--- a/src/pl/plpgsql/src/sql/plpgsql_simple.sql+++ b/src/pl/plpgsql/src/sql/plpgsql_simple.sql@@ -114,3 +114,36 @@ begin
fetch p_CurData into val;
raise notice 'val = %', val;
end; $$;
++-- Verify whether the behavior of the hold cursor is consistent during commit and rollback+do $$+declare+ p_CurData refcursor := 'hold_cursor';+ val int;+begin+ execute 'DECLARE hold_cursor CURSOR WITH HOLD FOR SELECT 42';+ loop+ fetch p_CurData into val;+ exit when val is null;+ raise notice 'val = %', val;+ commit;+ end loop;+ close p_CurData;+end; $$;++do $$+declare+ p_CurData refcursor := 'hold_cursor';+ val int;+begin+ execute 'DECLARE hold_cursor CURSOR WITH HOLD FOR SELECT 42';+ loop+ fetch p_CurData into val;+ exit when val is null;+ raise notice 'val = %', val;+ rollback;+ end loop;+ close p_CurData;+end; $$;++select * from pg_cursors;
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: zengman@halodbtech.com, pgsql-bugs@lists.postgresql.org
Subject: Re:BUG #19107: The hold cursor is unexpectedly released during rollback
In-Reply-To: <tencent_05B43F1B06161796748A12E1@qq.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox