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
pull/71/head
Tom Lane 5 years ago
parent 652f7818bf
commit a26194f22b
  1. 17
      contrib/bool_plperl/expected/bool_plperl.out
  2. 17
      contrib/bool_plperl/expected/bool_plperlu.out
  3. 6
      contrib/bool_plperl/sql/bool_plperl.sql
  4. 6
      contrib/bool_plperl/sql/bool_plperlu.sql
  5. 16
      contrib/hstore_plpython/expected/hstore_plpython.out
  6. 9
      contrib/hstore_plpython/sql/hstore_plpython.sql
  7. 3
      src/backend/utils/adt/ruleutils.c
  8. 5
      src/backend/utils/fmgr/funcapi.c

@ -52,7 +52,7 @@ SELECT perl2undef() IS NULL AS p;
--- test transforming to perl
CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void
LANGUAGE plperl
TRANSFORM FOR TYPE bool
TRANSFORM FOR TYPE bool, for type boolean -- duplicate to test ruleutils
AS $$
my ($x, $y, $z) = @_;
@ -68,6 +68,21 @@ SELECT bool2perl (true, false, NULL);
(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
CREATE FUNCTION spi_test() RETURNS void
LANGUAGE plperl

@ -52,7 +52,7 @@ SELECT perl2undef() IS NULL AS p;
--- test transforming to perl
CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void
LANGUAGE plperlu
TRANSFORM FOR TYPE bool
TRANSFORM FOR TYPE bool, for type boolean -- duplicate to test ruleutils
AS $$
my ($x, $y, $z) = @_;
@ -68,6 +68,21 @@ SELECT bool2perl (true, false, NULL);
(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
CREATE FUNCTION spi_test() RETURNS void
LANGUAGE plperlu

@ -33,7 +33,7 @@ SELECT perl2undef() IS NULL AS p;
CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void
LANGUAGE plperl
TRANSFORM FOR TYPE bool
TRANSFORM FOR TYPE bool, for type boolean -- duplicate to test ruleutils
AS $$
my ($x, $y, $z) = @_;
@ -46,6 +46,10 @@ $$;
SELECT bool2perl (true, false, NULL);
--- test ruleutils
\sf bool2perl
--- test selecting bool through SPI
CREATE FUNCTION spi_test() RETURNS void

@ -33,7 +33,7 @@ SELECT perl2undef() IS NULL AS p;
CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void
LANGUAGE plperlu
TRANSFORM FOR TYPE bool
TRANSFORM FOR TYPE bool, for type boolean -- duplicate to test ruleutils
AS $$
my ($x, $y, $z) = @_;
@ -46,6 +46,10 @@ $$;
SELECT bool2perl (true, false, NULL);
--- test ruleutils
\sf bool2perl
--- test selecting bool through SPI
CREATE FUNCTION spi_test() RETURNS void

@ -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

@ -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[]

@ -3127,13 +3127,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');
}
}

@ -1182,7 +1182,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,
@ -1211,7 +1213,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));

Loading…
Cancel
Save