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

Commit71caf3c

Browse files
committed
Fix handling of R/W expanded datums that are passed to SQL functions.
fmgr_sql must make expanded-datum arguments read-only, becauseit's possible that the function body will pass the argument tomore than one callee function. If one of those functions takesthe datum's R/W property as license to scribble on it, then latercallees will see an unexpected value, leading to wrong answers.From a performance standpoint, it'd be nice to skip this in thecommon case that the argument value is passed to only one callee.However, detecting that seems fairly hard, and certainly notsomething that I care to attempt in a back-patched bug fix.Per report from Adam Mackler. This has been broken since weinvented expanded datums, so back-patch to all supported branches.Discussion:https://postgr.es/m/WScDU5qfoZ7PB2gXwNqwGGgDPmWzz08VdydcPFLhOwUKZcdWbblbo-0Lku-qhuEiZoXJ82jpiQU4hOjOcrevYEDeoAvz6nR0IU4IHhXnaCA=@mackler.emailDiscussion:https://postgr.es/m/187436.1660143060@sss.pgh.pa.us
1 parent4bc493d commit71caf3c

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

‎src/backend/executor/functions.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,7 @@ postquel_sub_params(SQLFunctionCachePtr fcache,
923923
if (nargs>0)
924924
{
925925
ParamListInfoparamLI;
926+
Oid*argtypes=fcache->pinfo->argtypes;
926927

927928
if (fcache->paramLI==NULL)
928929
{
@@ -939,10 +940,24 @@ postquel_sub_params(SQLFunctionCachePtr fcache,
939940
{
940941
ParamExternData*prm=&paramLI->params[i];
941942

942-
prm->value=fcinfo->args[i].value;
943+
/*
944+
* If an incoming parameter value is a R/W expanded datum, we
945+
* force it to R/O. We'd be perfectly entitled to scribble on it,
946+
* but the problem is that if the parameter is referenced more
947+
* than once in the function, earlier references might mutate the
948+
* value seen by later references, which won't do at all. We
949+
* could do better if we could be sure of the number of Param
950+
* nodes in the function's plans; but we might not have planned
951+
* all the statements yet, nor do we have plan tree walker
952+
* infrastructure. (Examining the parse trees is not good enough,
953+
* because of possible function inlining during planning.)
954+
*/
943955
prm->isnull=fcinfo->args[i].isnull;
956+
prm->value=MakeExpandedObjectReadOnly(fcinfo->args[i].value,
957+
prm->isnull,
958+
get_typlen(argtypes[i]));
944959
prm->pflags=0;
945-
prm->ptype=fcache->pinfo->argtypes[i];
960+
prm->ptype=argtypes[i];
946961
}
947962
}
948963
else

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,9 +340,25 @@ SELECT * FROM voidtest5(3);
340340
-----------
341341
(0 rows)
342342

343+
-- Regression tests for bugs:
344+
-- Check that arguments that are R/W expanded datums aren't corrupted by
345+
-- multiple uses. This test knows that array_append() returns a R/W datum
346+
-- and will modify a R/W array input in-place. We use SETOF to prevent
347+
-- inlining of the SQL function.
348+
CREATE FUNCTION double_append(anyarray, anyelement) RETURNS SETOF anyarray
349+
LANGUAGE SQL IMMUTABLE AS
350+
$$ SELECT array_append($1, $2) || array_append($1, $2) $$;
351+
SELECT double_append(array_append(ARRAY[q1], q2), q3)
352+
FROM (VALUES(1,2,3), (4,5,6)) v(q1,q2,q3);
353+
double_append
354+
---------------
355+
{1,2,3,1,2,3}
356+
{4,5,6,4,5,6}
357+
(2 rows)
358+
343359
-- Cleanup
344360
DROP SCHEMA temp_func_test CASCADE;
345-
NOTICE: drop cascades to21 other objects
361+
NOTICE: drop cascades to22 other objects
346362
DETAIL: drop cascades to function functest_a_1(text,date)
347363
drop cascades to function functest_a_2(text[])
348364
drop cascades to function functest_a_3()
@@ -364,5 +380,6 @@ drop cascades to function voidtest2(integer,integer)
364380
drop cascades to function voidtest3(integer)
365381
drop cascades to function voidtest4(integer)
366382
drop cascades to function voidtest5(integer)
383+
drop cascades to function double_append(anyarray,anyelement)
367384
DROP USER regress_unpriv_user;
368385
RESET search_path;

‎src/test/regress/sql/create_function_3.sql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,19 @@ CREATE FUNCTION voidtest5(a int) RETURNS SETOF VOID LANGUAGE SQL AS
219219
$$SELECT generate_series(1, a) $$ STABLE;
220220
SELECT*FROM voidtest5(3);
221221

222+
-- Regression tests for bugs:
223+
224+
-- Check that arguments that are R/W expanded datums aren't corrupted by
225+
-- multiple uses. This test knows that array_append() returns a R/W datum
226+
-- and will modify a R/W array input in-place. We use SETOF to prevent
227+
-- inlining of the SQL function.
228+
CREATEFUNCTIONdouble_append(anyarray, anyelement) RETURNS SETOF anyarray
229+
LANGUAGE SQL IMMUTABLEAS
230+
$$SELECT array_append($1, $2)|| array_append($1, $2) $$;
231+
232+
SELECT double_append(array_append(ARRAY[q1], q2), q3)
233+
FROM (VALUES(1,2,3), (4,5,6)) v(q1,q2,q3);
234+
222235
-- Cleanup
223236
DROPSCHEMA temp_func_test CASCADE;
224237
DROPUSER regress_unpriv_user;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp