Commit 07d46fce authored by Tom Lane's avatar Tom Lane

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
parent d18e7566
...@@ -52,7 +52,7 @@ SELECT perl2undef() IS NULL AS p; ...@@ -52,7 +52,7 @@ SELECT perl2undef() IS NULL AS p;
--- test transforming to perl --- test transforming to perl
CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void
LANGUAGE plperl LANGUAGE plperl
TRANSFORM FOR TYPE bool TRANSFORM FOR TYPE bool, for type boolean -- duplicate to test ruleutils
AS $$ AS $$
my ($x, $y, $z) = @_; my ($x, $y, $z) = @_;
...@@ -68,6 +68,21 @@ SELECT bool2perl (true, false, NULL); ...@@ -68,6 +68,21 @@ SELECT bool2perl (true, false, NULL);
(1 row) (1 row)
--- test ruleutils
\sf bool2perl
CREATE OR REPLACE FUNCTION public.bool2perl(boolean, boolean, boolean)
RETURNS void
TRANSFORM FOR TYPE boolean, FOR TYPE boolean
LANGUAGE plperl
AS $function$
my ($x, $y, $z) = @_;
die("NULL mistransformed") if (defined($z));
die("TRUE mistransformed to UNDEF") if (!defined($x));
die("FALSE mistransformed to UNDEF") if (!defined($y));
die("TRUE mistransformed") if (!$x);
die("FALSE mistransformed") if ($y);
$function$
--- test selecting bool through SPI --- test selecting bool through SPI
CREATE FUNCTION spi_test() RETURNS void CREATE FUNCTION spi_test() RETURNS void
LANGUAGE plperl LANGUAGE plperl
......
...@@ -52,7 +52,7 @@ SELECT perl2undef() IS NULL AS p; ...@@ -52,7 +52,7 @@ SELECT perl2undef() IS NULL AS p;
--- test transforming to perl --- test transforming to perl
CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void
LANGUAGE plperlu LANGUAGE plperlu
TRANSFORM FOR TYPE bool TRANSFORM FOR TYPE bool, for type boolean -- duplicate to test ruleutils
AS $$ AS $$
my ($x, $y, $z) = @_; my ($x, $y, $z) = @_;
...@@ -68,6 +68,21 @@ SELECT bool2perl (true, false, NULL); ...@@ -68,6 +68,21 @@ SELECT bool2perl (true, false, NULL);
(1 row) (1 row)
--- test ruleutils
\sf bool2perl
CREATE OR REPLACE FUNCTION public.bool2perl(boolean, boolean, boolean)
RETURNS void
TRANSFORM FOR TYPE boolean, FOR TYPE boolean
LANGUAGE plperlu
AS $function$
my ($x, $y, $z) = @_;
die("NULL mistransformed") if (defined($z));
die("TRUE mistransformed to UNDEF") if (!defined($x));
die("FALSE mistransformed to UNDEF") if (!defined($y));
die("TRUE mistransformed") if (!$x);
die("FALSE mistransformed") if ($y);
$function$
--- test selecting bool through SPI --- test selecting bool through SPI
CREATE FUNCTION spi_test() RETURNS void CREATE FUNCTION spi_test() RETURNS void
LANGUAGE plperlu LANGUAGE plperlu
......
...@@ -33,7 +33,7 @@ SELECT perl2undef() IS NULL AS p; ...@@ -33,7 +33,7 @@ SELECT perl2undef() IS NULL AS p;
CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void
LANGUAGE plperl LANGUAGE plperl
TRANSFORM FOR TYPE bool TRANSFORM FOR TYPE bool, for type boolean -- duplicate to test ruleutils
AS $$ AS $$
my ($x, $y, $z) = @_; my ($x, $y, $z) = @_;
...@@ -46,6 +46,10 @@ $$; ...@@ -46,6 +46,10 @@ $$;
SELECT bool2perl (true, false, NULL); SELECT bool2perl (true, false, NULL);
--- test ruleutils
\sf bool2perl
--- test selecting bool through SPI --- test selecting bool through SPI
CREATE FUNCTION spi_test() RETURNS void CREATE FUNCTION spi_test() RETURNS void
......
...@@ -33,7 +33,7 @@ SELECT perl2undef() IS NULL AS p; ...@@ -33,7 +33,7 @@ SELECT perl2undef() IS NULL AS p;
CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void
LANGUAGE plperlu LANGUAGE plperlu
TRANSFORM FOR TYPE bool TRANSFORM FOR TYPE bool, for type boolean -- duplicate to test ruleutils
AS $$ AS $$
my ($x, $y, $z) = @_; my ($x, $y, $z) = @_;
...@@ -46,6 +46,10 @@ $$; ...@@ -46,6 +46,10 @@ $$;
SELECT bool2perl (true, false, NULL); SELECT bool2perl (true, false, NULL);
--- test ruleutils
\sf bool2perl
--- test selecting bool through SPI --- test selecting bool through SPI
CREATE FUNCTION spi_test() RETURNS void CREATE FUNCTION spi_test() RETURNS void
......
...@@ -47,19 +47,29 @@ SELECT test1arr(array['aa=>bb, cc=>NULL'::hstore, 'dd=>ee']); ...@@ -47,19 +47,29 @@ SELECT test1arr(array['aa=>bb, cc=>NULL'::hstore, 'dd=>ee']);
(1 row) (1 row)
-- test python -> hstore -- test python -> hstore
CREATE FUNCTION test2() RETURNS hstore CREATE FUNCTION test2(a int, b text) RETURNS hstore
LANGUAGE plpythonu LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore TRANSFORM FOR TYPE hstore
AS $$ AS $$
val = {'a': 1, 'b': 'boo', 'c': None} val = {'a': a, 'b': b, 'c': None}
return val return val
$$; $$;
SELECT test2(); SELECT test2(1, 'boo');
test2 test2
--------------------------------- ---------------------------------
"a"=>"1", "b"=>"boo", "c"=>NULL "a"=>"1", "b"=>"boo", "c"=>NULL
(1 row) (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[] -- test python -> hstore[]
CREATE FUNCTION test2arr() RETURNS hstore[] CREATE FUNCTION test2arr() RETURNS hstore[]
LANGUAGE plpythonu LANGUAGE plpythonu
......
...@@ -40,15 +40,18 @@ SELECT test1arr(array['aa=>bb, cc=>NULL'::hstore, 'dd=>ee']); ...@@ -40,15 +40,18 @@ SELECT test1arr(array['aa=>bb, cc=>NULL'::hstore, 'dd=>ee']);
-- test python -> hstore -- test python -> hstore
CREATE FUNCTION test2() RETURNS hstore CREATE FUNCTION test2(a int, b text) RETURNS hstore
LANGUAGE plpythonu LANGUAGE plpythonu
TRANSFORM FOR TYPE hstore TRANSFORM FOR TYPE hstore
AS $$ AS $$
val = {'a': 1, 'b': 'boo', 'c': None} val = {'a': a, 'b': b, 'c': None}
return val return val
$$; $$;
SELECT test2(); SELECT test2(1, 'boo');
--- test ruleutils
\sf test2
-- test python -> hstore[] -- test python -> hstore[]
......
...@@ -3126,13 +3126,14 @@ print_function_trftypes(StringInfo buf, HeapTuple proctup) ...@@ -3126,13 +3126,14 @@ print_function_trftypes(StringInfo buf, HeapTuple proctup)
{ {
int i; int i;
appendStringInfoString(buf, "\n TRANSFORM "); appendStringInfoString(buf, " TRANSFORM ");
for (i = 0; i < ntypes; i++) for (i = 0; i < ntypes; i++)
{ {
if (i != 0) if (i != 0)
appendStringInfoString(buf, ", "); appendStringInfoString(buf, ", ");
appendStringInfo(buf, "FOR TYPE %s", format_type_be(trftypes[i])); appendStringInfo(buf, "FOR TYPE %s", format_type_be(trftypes[i]));
} }
appendStringInfoChar(buf, '\n');
} }
} }
......
...@@ -1357,7 +1357,9 @@ get_func_arg_info(HeapTuple procTup, ...@@ -1357,7 +1357,9 @@ get_func_arg_info(HeapTuple procTup,
/* /*
* get_func_trftypes * 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 int
get_func_trftypes(HeapTuple procTup, get_func_trftypes(HeapTuple procTup,
...@@ -1386,7 +1388,6 @@ get_func_trftypes(HeapTuple procTup, ...@@ -1386,7 +1388,6 @@ get_func_trftypes(HeapTuple procTup,
ARR_HASNULL(arr) || ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != OIDOID) ARR_ELEMTYPE(arr) != OIDOID)
elog(ERROR, "protrftypes is not a 1-D Oid array or it contains nulls"); elog(ERROR, "protrftypes is not a 1-D Oid array or it contains nulls");
Assert(nelems >= ((Form_pg_proc) GETSTRUCT(procTup))->pronargs);
*p_trftypes = (Oid *) palloc(nelems * sizeof(Oid)); *p_trftypes = (Oid *) palloc(nelems * sizeof(Oid));
memcpy(*p_trftypes, ARR_DATA_PTR(arr), memcpy(*p_trftypes, ARR_DATA_PTR(arr),
nelems * sizeof(Oid)); nelems * sizeof(Oid));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment