aboutsummaryrefslogtreecommitdiff
path: root/src/test/regress/sql/create_function_sql.sql
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-08-10 13:37:25 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2022-08-10 13:37:25 -0400
commitad3e07c156544f31d02e55e95ba7954ea87a2ee8 (patch)
tree833e2583d219dd6835f24192ee6cd273247ad5c9 /src/test/regress/sql/create_function_sql.sql
parentdf64c24a31e110327135a8590c4500887e4773ae (diff)
downloadpostgresql-ad3e07c156544f31d02e55e95ba7954ea87a2ee8.tar.gz
postgresql-ad3e07c156544f31d02e55e95ba7954ea87a2ee8.zip
Fix handling of R/W expanded datums that are passed to SQL functions.
fmgr_sql must make expanded-datum arguments read-only, because it's possible that the function body will pass the argument to more than one callee function. If one of those functions takes the datum's R/W property as license to scribble on it, then later callees will see an unexpected value, leading to wrong answers. From a performance standpoint, it'd be nice to skip this in the common case that the argument value is passed to only one callee. However, detecting that seems fairly hard, and certainly not something that I care to attempt in a back-patched bug fix. Per report from Adam Mackler. This has been broken since we invented expanded datums, so back-patch to all supported branches. Discussion: https://postgr.es/m/WScDU5qfoZ7PB2gXwNqwGGgDPmWzz08VdydcPFLhOwUKZcdWbblbo-0Lku-qhuEiZoXJ82jpiQU4hOjOcrevYEDeoAvz6nR0IU4IHhXnaCA=@mackler.email Discussion: https://postgr.es/m/187436.1660143060@sss.pgh.pa.us
Diffstat (limited to 'src/test/regress/sql/create_function_sql.sql')
-rw-r--r--src/test/regress/sql/create_function_sql.sql13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/test/regress/sql/create_function_sql.sql b/src/test/regress/sql/create_function_sql.sql
index cc0ccd8db12..89e9af3a499 100644
--- a/src/test/regress/sql/create_function_sql.sql
+++ b/src/test/regress/sql/create_function_sql.sql
@@ -385,6 +385,19 @@ CREATE FUNCTION voidtest5(a int) RETURNS SETOF VOID LANGUAGE SQL AS
$$ SELECT generate_series(1, a) $$ STABLE;
SELECT * FROM voidtest5(3);
+-- Regression tests for bugs:
+
+-- Check that arguments that are R/W expanded datums aren't corrupted by
+-- multiple uses. This test knows that array_append() returns a R/W datum
+-- and will modify a R/W array input in-place. We use SETOF to prevent
+-- inlining of the SQL function.
+CREATE FUNCTION double_append(anyarray, anyelement) RETURNS SETOF anyarray
+LANGUAGE SQL IMMUTABLE AS
+$$ SELECT array_append($1, $2) || array_append($1, $2) $$;
+
+SELECT double_append(array_append(ARRAY[q1], q2), q3)
+ FROM (VALUES(1,2,3), (4,5,6)) v(q1,q2,q3);
+
-- Things that shouldn't work:
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL