Fix thinko in plpgsql memory leak fix.

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
This commit is contained in:
Tom Lane 2020-12-28 11:41:25 -05:00
parent 643428c54b
commit ea80d8d943
3 changed files with 47 additions and 2 deletions

View 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

View File

@ -2235,8 +2235,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

View 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