Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Fix thinko in plpgsql memory leak fix.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 28 Dec 2020 16:41:25 +0000 (11:41 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 28 Dec 2020 16:41:25 +0000 (11:41 -0500)
Commit a6b1f5365 intended to place the transient "target" list of
a CALL statement in the function's statement-lifespan context,
but I fat-fingered that and used get_eval_mcontext() instead of
get_stmt_mcontext().  The eval_mcontext belongs to the "simple
expression" infrastructure, which is destroyed at transaction end.
The net effect is that a CALL in a procedure to another procedure
that has OUT or INOUT parameters would fail if the called procedure
did a COMMIT.

Per report from Peter Eisentraut.  Back-patch to v11, like the
prior patch.

Discussion: https://postgr.es/m/f075f7be-c654-9aa8-3ffc-e9214622f02a@enterprisedb.com

src/pl/plpgsql/src/expected/plpgsql_call.out
src/pl/plpgsql/src/pl_exec.c
src/pl/plpgsql/src/sql/plpgsql_call.sql

index d9c88e85c8d8725b15446abc8968198f2ae86144..fbe8a046067f21aa5a2cad88598fb9ceb829f5c9 100644 (file)
@@ -152,6 +152,27 @@ CALL test_proc7(100, -1, -1);
  0 | 1
 (1 row)
 
+-- inner COMMIT with output arguments
+CREATE PROCEDURE test_proc7c(x int, INOUT a int, INOUT b numeric)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+  a := x / 10;
+  b := x / 2;
+  COMMIT;
+END;
+$$;
+CREATE PROCEDURE test_proc7cc(_x int)
+LANGUAGE plpgsql
+AS $$
+DECLARE _a int; _b numeric;
+BEGIN
+  CALL test_proc7c(_x, _a, _b);
+  RAISE NOTICE '_x: %,_a: %, _b: %', _x, _a, _b;
+END
+$$;
+CALL test_proc7cc(10);
+NOTICE:  _x: 10,_a: 1, _b: 5
 -- named parameters and defaults
 CREATE PROCEDURE test_proc8a(INOUT a int, INOUT b int)
 LANGUAGE plpgsql
index ea134ba72e635fd11b97ebee2e28676ac97b80f7..462ce4d170e656224589b79fc9a7069671495954 100644 (file)
@@ -2224,8 +2224,8 @@ exec_stmt_call(PLpgSQL_execstate *estate, PLpgSQL_stmt_call *stmt)
            int         i;
            ListCell   *lc;
 
-           /* Use eval_mcontext for any cruft accumulated here */
-           oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate));
+           /* Use stmt_mcontext for any cruft accumulated here */
+           oldcontext = MemoryContextSwitchTo(get_stmt_mcontext(estate));
 
            /*
             * Get the parsed CallStmt, and look up the called procedure
index 4702bd14d12e89238d6a100c77c88ba3560c6af2..21b4a37e59b0f1e0491a260eeb91ab84c6d8f446 100644 (file)
@@ -141,6 +141,30 @@ $$;
 
 CALL test_proc7(100, -1, -1);
 
+-- inner COMMIT with output arguments
+
+CREATE PROCEDURE test_proc7c(x int, INOUT a int, INOUT b numeric)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+  a := x / 10;
+  b := x / 2;
+  COMMIT;
+END;
+$$;
+
+CREATE PROCEDURE test_proc7cc(_x int)
+LANGUAGE plpgsql
+AS $$
+DECLARE _a int; _b numeric;
+BEGIN
+  CALL test_proc7c(_x, _a, _b);
+  RAISE NOTICE '_x: %,_a: %, _b: %', _x, _a, _b;
+END
+$$;
+
+CALL test_proc7cc(10);
+
 
 -- named parameters and defaults