Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitef2b138

Browse files
committed
Fix incorrect logic in plpgsql for cleanup after evaluation of non-simple
expressions. We need to deal with this when handling subscripts in an arrayassignment, and also when catching an exception. In an Assert-enabled buildthese omissions led to Assert failures, but I think in a normal build theonly consequence would be short-term memory leakage; which may explain whythis wasn't reported from the field long ago.Back-patch to all supported versions. 7.4 doesn't have exceptions, butotherwise these bugs go all the way back.Heikki Linnakangas and Tom Lane
1 parent10c0565 commitef2b138

File tree

3 files changed

+80
-2
lines changed

3 files changed

+80
-2
lines changed

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.93.2.4 2010/07/05 09:27:57 heikki Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.93.2.5 2010/08/09 18:51:12 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -1919,6 +1919,9 @@ plpgsql_estate_setup(PLpgSQL_execstate * estate,
19191919
*
19201920
* NB: the result of the evaluation is no longer valid after this is done,
19211921
* unless it is a pass-by-value datatype.
1922+
*
1923+
* NB: if you change this code, see also the hacks in exec_assign_value's
1924+
* PLPGSQL_DTYPE_ARRAYELEM case.
19221925
* ----------
19231926
*/
19241927
staticvoid
@@ -2674,6 +2677,10 @@ exec_assign_expr(PLpgSQL_execstate * estate, PLpgSQL_datum * target,
26742677

26752678
/* ----------
26762679
* exec_assign_valuePut a value into a target field
2680+
*
2681+
* Note: in some code paths, this may leak memory in the eval_econtext;
2682+
* we assume that will be cleaned up later by exec_eval_cleanup. We cannot
2683+
* call exec_eval_cleanup here for fear of destroying the input Datum value.
26772684
* ----------
26782685
*/
26792686
staticvoid
@@ -2708,6 +2715,7 @@ exec_assign_value(PLpgSQL_execstate * estate,
27082715
Datumoldarrayval,
27092716
coerced_value;
27102717
ArrayType*newarrayval;
2718+
SPITupleTable*save_eval_tuptable;
27112719
HeapTuplenewtup;
27122720

27132721
switch (target->dtype)
@@ -2868,6 +2876,16 @@ exec_assign_value(PLpgSQL_execstate * estate,
28682876
/*
28692877
* Target is an element of an array
28702878
*
2879+
* We need to do subscript evaluation, which might require
2880+
* evaluating general expressions; and the caller might have
2881+
* done that too in order to prepare the input Datum. We
2882+
* have to save and restore the caller's SPI_execute result,
2883+
* if any.
2884+
*/
2885+
save_eval_tuptable=estate->eval_tuptable;
2886+
estate->eval_tuptable=NULL;
2887+
2888+
/*
28712889
* To handle constructs like x[1][2] := something, we have to be
28722890
* prepared to deal with a chain of arrayelem datums. Chase
28732891
* back to find the base array datum, and save the subscript
@@ -2910,8 +2928,23 @@ exec_assign_value(PLpgSQL_execstate * estate,
29102928
subscripts[nsubscripts-1-i],
29112929
&subisnull);
29122930
havenullsubscript |=subisnull;
2931+
2932+
/*
2933+
* Clean up in case the subscript expression wasn't simple.
2934+
* We can't do exec_eval_cleanup, but we can do this much
2935+
* (which is safe because the integer subscript value is
2936+
* surely pass-by-value), and we must do it in case the
2937+
* next subscript expression isn't simple either.
2938+
*/
2939+
if (estate->eval_tuptable!=NULL)
2940+
SPI_freetuptable(estate->eval_tuptable);
2941+
estate->eval_tuptable=NULL;
29132942
}
29142943

2944+
/* Now we can restore caller's SPI_execute result if any. */
2945+
Assert(estate->eval_tuptable==NULL);
2946+
estate->eval_tuptable=save_eval_tuptable;
2947+
29152948
/*
29162949
* Skip the assignment if we have any nulls, either in the
29172950
* original array value, the subscripts, or the righthand

‎src/test/regress/expected/plpgsql.out

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,3 +1788,26 @@ SELECT * FROM perform_test;
17881788
(3 rows)
17891789

17901790
drop table perform_test;
1791+
-- Test for appropriate cleanup of non-simple expression evaluations
1792+
-- (bug in all versions prior to August 2010)
1793+
CREATE FUNCTION nonsimple_expr_test() RETURNS text[] AS '
1794+
DECLARE
1795+
arr text[];
1796+
lr text;
1797+
i integer;
1798+
BEGIN
1799+
arr := array[array[''foo'',''bar''], array[''baz'', ''quux'']];
1800+
lr := ''fool'';
1801+
i := 1;
1802+
-- use sub-SELECTs to make expressions non-simple
1803+
arr[(SELECT i)][(SELECT i+1)] := (SELECT lr);
1804+
RETURN arr;
1805+
END;
1806+
' LANGUAGE plpgsql;
1807+
SELECT nonsimple_expr_test();
1808+
nonsimple_expr_test
1809+
-------------------------
1810+
{{foo,fool},{baz,quux}}
1811+
(1 row)
1812+
1813+
DROP FUNCTION nonsimple_expr_test();

‎src/test/regress/sql/plpgsql.sql

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1603,4 +1603,26 @@ END;' language 'plpgsql';
16031603
SELECT perform_test_func();
16041604
SELECT*FROM perform_test;
16051605

1606-
droptable perform_test;
1606+
droptable perform_test;
1607+
1608+
-- Test for appropriate cleanup of non-simple expression evaluations
1609+
-- (bug in all versions prior to August 2010)
1610+
1611+
CREATEFUNCTIONnonsimple_expr_test() RETURNStext[]AS'
1612+
DECLARE
1613+
arr text[];
1614+
lr text;
1615+
i integer;
1616+
BEGIN
1617+
arr := array[array[''foo'',''bar''], array[''baz'',''quux'']];
1618+
lr :=''fool'';
1619+
i := 1;
1620+
-- use sub-SELECTs to make expressions non-simple
1621+
arr[(SELECT i)][(SELECT i+1)] := (SELECT lr);
1622+
RETURN arr;
1623+
END;
1624+
' LANGUAGE plpgsql;
1625+
1626+
SELECT nonsimple_expr_test();
1627+
1628+
DROPFUNCTION nonsimple_expr_test();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp