pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
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.c
index 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.out
index 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.sql
index 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;


view thread (4+ messages)  latest in thread

Message-ID: <tencent_05B43F1B06161796748A12E1@qq.com>
Permalink:  ../tencent_05B43F1B06161796748A12E1@qq.com/
Also on:    postgresql.org/message-id/tencent_05B43F1B06161796748A12E1@qq.com

 ·  · 

reply

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