From 4641b2a30f0a2353e875cba48193e33d8ca0b173 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 25 Jan 2021 13:03:11 -0500 Subject: [PATCH] Fix broken ruleutils support for function TRANSFORM clauses. I chanced to notice that this dumped core due to a faulty Assert. To add insult to injury, the output has been misformatted since v11. Obviously we need some regression testing here. Discussion: https://postgr.es/m/d1cc628c-3953-4209-957b-29427acc38c8@www.fastmail.com --- .../hstore_plpython/expected/hstore_plpython.out | 16 +++++++++++++--- contrib/hstore_plpython/sql/hstore_plpython.sql | 9 ++++++--- src/backend/utils/adt/ruleutils.c | 3 ++- src/backend/utils/fmgr/funcapi.c | 5 +++-- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/contrib/hstore_plpython/expected/hstore_plpython.out b/contrib/hstore_plpython/expected/hstore_plpython.out index 1ab5feea93..ecf1dd61bc 100644 --- a/contrib/hstore_plpython/expected/hstore_plpython.out +++ b/contrib/hstore_plpython/expected/hstore_plpython.out @@ -47,19 +47,29 @@ SELECT test1arr(array['aa=>bb, cc=>NULL'::hstore, 'dd=>ee']); (1 row) -- test python -> hstore -CREATE FUNCTION test2() RETURNS hstore +CREATE FUNCTION test2(a int, b text) RETURNS hstore LANGUAGE plpythonu TRANSFORM FOR TYPE hstore AS $$ -val = {'a': 1, 'b': 'boo', 'c': None} +val = {'a': a, 'b': b, 'c': None} return val $$; -SELECT test2(); +SELECT test2(1, 'boo'); test2 --------------------------------- "a"=>"1", "b"=>"boo", "c"=>NULL (1 row) +--- test ruleutils +\sf test2 +CREATE OR REPLACE FUNCTION public.test2(a integer, b text) + RETURNS hstore + TRANSFORM FOR TYPE hstore + LANGUAGE plpythonu +AS $function$ +val = {'a': a, 'b': b, 'c': None} +return val +$function$ -- test python -> hstore[] CREATE FUNCTION test2arr() RETURNS hstore[] LANGUAGE plpythonu diff --git a/contrib/hstore_plpython/sql/hstore_plpython.sql b/contrib/hstore_plpython/sql/hstore_plpython.sql index 2c54ee6aaa..b6d98b7dd5 100644 --- a/contrib/hstore_plpython/sql/hstore_plpython.sql +++ b/contrib/hstore_plpython/sql/hstore_plpython.sql @@ -40,15 +40,18 @@ SELECT test1arr(array['aa=>bb, cc=>NULL'::hstore, 'dd=>ee']); -- test python -> hstore -CREATE FUNCTION test2() RETURNS hstore +CREATE FUNCTION test2(a int, b text) RETURNS hstore LANGUAGE plpythonu TRANSFORM FOR TYPE hstore AS $$ -val = {'a': 1, 'b': 'boo', 'c': None} +val = {'a': a, 'b': b, 'c': None} return val $$; -SELECT test2(); +SELECT test2(1, 'boo'); + +--- test ruleutils +\sf test2 -- test python -> hstore[] diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 1268ac1dd0..b76ae9fddd 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3103,13 +3103,14 @@ print_function_trftypes(StringInfo buf, HeapTuple proctup) { int i; - appendStringInfoString(buf, "\n TRANSFORM "); + appendStringInfoString(buf, " TRANSFORM "); for (i = 0; i < ntypes; i++) { if (i != 0) appendStringInfoString(buf, ", "); appendStringInfo(buf, "FOR TYPE %s", format_type_be(trftypes[i])); } + appendStringInfoChar(buf, '\n'); } } diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c index 206c3bd13e..8632b1a296 100644 --- a/src/backend/utils/fmgr/funcapi.c +++ b/src/backend/utils/fmgr/funcapi.c @@ -972,7 +972,9 @@ get_func_arg_info(HeapTuple procTup, /* * get_func_trftypes * - * Returns the number of transformed types used by function. + * Returns the number of transformed types used by the function. + * If there are any, a palloc'd array of the type OIDs is returned + * into *p_trftypes. */ int get_func_trftypes(HeapTuple procTup, @@ -1001,7 +1003,6 @@ get_func_trftypes(HeapTuple procTup, ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != OIDOID) elog(ERROR, "protrftypes is not a 1-D Oid array"); - Assert(nelems >= ((Form_pg_proc) GETSTRUCT(procTup))->pronargs); *p_trftypes = (Oid *) palloc(nelems * sizeof(Oid)); memcpy(*p_trftypes, ARR_DATA_PTR(arr), nelems * sizeof(Oid));