001_rollback_no_release_holdcursor.patch
application/octet-stream
Filename: 001_rollback_no_release_holdcursor.patch
Type: application/octet-stream
Part: 0
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;