aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/mmgr/portalmem.c14
-rw-r--r--src/pl/plpgsql/src/expected/plpgsql_transaction.out30
-rw-r--r--src/pl/plpgsql/src/sql/plpgsql_transaction.sql25
3 files changed, 67 insertions, 2 deletions
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 04ea32f49f2..d34cab0eb88 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -689,13 +689,23 @@ PreCommit_Portals(bool isPrepare)
/*
* Do not touch active portals --- this can only happen in the case of
- * a multi-transaction utility command, such as VACUUM.
+ * a multi-transaction utility command, such as VACUUM, or a commit in
+ * a procedure.
*
* Note however that any resource owner attached to such a portal is
- * still going to go away, so don't leave a dangling pointer.
+ * still going to go away, so don't leave a dangling pointer. Also
+ * unregister any snapshots held by the portal, mainly to avoid
+ * snapshot leak warnings from ResourceOwnerRelease().
*/
if (portal->status == PORTAL_ACTIVE)
{
+ if (portal->holdSnapshot)
+ {
+ if (portal->resowner)
+ UnregisterSnapshotFromOwner(portal->holdSnapshot,
+ portal->resowner);
+ portal->holdSnapshot = NULL;
+ }
portal->resowner = NULL;
continue;
}
diff --git a/src/pl/plpgsql/src/expected/plpgsql_transaction.out b/src/pl/plpgsql/src/expected/plpgsql_transaction.out
index 0b5a039b89c..77a83adab54 100644
--- a/src/pl/plpgsql/src/expected/plpgsql_transaction.out
+++ b/src/pl/plpgsql/src/expected/plpgsql_transaction.out
@@ -463,6 +463,36 @@ SELECT * FROM test2;
42
(1 row)
+-- Test transaction in procedure with output parameters. This uses a
+-- different portal strategy and different code paths in pquery.c.
+CREATE PROCEDURE transaction_test10a(INOUT x int)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ x := x + 1;
+ COMMIT;
+END;
+$$;
+CALL transaction_test10a(10);
+ x
+----
+ 11
+(1 row)
+
+CREATE PROCEDURE transaction_test10b(INOUT x int)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ x := x - 1;
+ ROLLBACK;
+END;
+$$;
+CALL transaction_test10b(10);
+ x
+---
+ 9
+(1 row)
+
DROP TABLE test1;
DROP TABLE test2;
DROP TABLE test3;
diff --git a/src/pl/plpgsql/src/sql/plpgsql_transaction.sql b/src/pl/plpgsql/src/sql/plpgsql_transaction.sql
index 236db9bf2bf..0ed9ab873a4 100644
--- a/src/pl/plpgsql/src/sql/plpgsql_transaction.sql
+++ b/src/pl/plpgsql/src/sql/plpgsql_transaction.sql
@@ -387,6 +387,31 @@ $$;
SELECT * FROM test2;
+-- Test transaction in procedure with output parameters. This uses a
+-- different portal strategy and different code paths in pquery.c.
+CREATE PROCEDURE transaction_test10a(INOUT x int)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ x := x + 1;
+ COMMIT;
+END;
+$$;
+
+CALL transaction_test10a(10);
+
+CREATE PROCEDURE transaction_test10b(INOUT x int)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ x := x - 1;
+ ROLLBACK;
+END;
+$$;
+
+CALL transaction_test10b(10);
+
+
DROP TABLE test1;
DROP TABLE test2;
DROP TABLE test3;