mirror of
https://git.postgresql.org/git/postgresql.git
synced 2026-02-22 06:17:00 +08:00
Fix incorrect logic in plpgsql for cleanup after evaluation of non-simple
expressions. We need to deal with this when handling subscripts in an array assignment, and also when catching an exception. In an Assert-enabled build these omissions led to Assert failures, but I think in a normal build the only consequence would be short-term memory leakage; which may explain why this wasn't reported from the field long ago. Back-patch to all supported versions. 7.4 doesn't have exceptions, but otherwise these bugs go all the way back. Heikki Linnakangas and Tom Lane
This commit is contained in:
@ -3125,6 +3125,46 @@ SELECT * FROM leaker_1(true);
|
||||
DROP FUNCTION leaker_1(bool);
|
||||
DROP FUNCTION leaker_2(bool);
|
||||
|
||||
-- Test for appropriate cleanup of non-simple expression evaluations
|
||||
-- (bug in all versions prior to August 2010)
|
||||
|
||||
CREATE FUNCTION nonsimple_expr_test() RETURNS text[] AS $$
|
||||
DECLARE
|
||||
arr text[];
|
||||
lr text;
|
||||
i integer;
|
||||
BEGIN
|
||||
arr := array[array['foo','bar'], array['baz', 'quux']];
|
||||
lr := 'fool';
|
||||
i := 1;
|
||||
-- use sub-SELECTs to make expressions non-simple
|
||||
arr[(SELECT i)][(SELECT i+1)] := (SELECT lr);
|
||||
RETURN arr;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
SELECT nonsimple_expr_test();
|
||||
|
||||
DROP FUNCTION nonsimple_expr_test();
|
||||
|
||||
CREATE FUNCTION nonsimple_expr_test() RETURNS integer AS $$
|
||||
declare
|
||||
i integer NOT NULL := 0;
|
||||
begin
|
||||
begin
|
||||
i := (SELECT NULL::integer); -- should throw error
|
||||
exception
|
||||
WHEN OTHERS THEN
|
||||
i := (SELECT 1::integer);
|
||||
end;
|
||||
return i;
|
||||
end;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
SELECT nonsimple_expr_test();
|
||||
|
||||
DROP FUNCTION nonsimple_expr_test();
|
||||
|
||||
-- Test handling of string literals.
|
||||
|
||||
set standard_conforming_strings = off;
|
||||
|
||||
Reference in New Issue
Block a user