plperl returning setof foo[]

Started by Andrew Dunstanover 16 years ago5 messages
#1Andrew Dunstan
andrew@dunslane.net
1 attachment(s)

I have just noticed, somewhat to my chagrin, that while in a plperl
function that returns an array type you can return a perl arrayref, like
this:

return [qw(a b c)];

if the function returns a setof an array type you cannot do this:

return_next [qw(a b c)];

Now the plperl docs say:

Perl can return PostgreSQL arrays as references to Perl arrays. Here
is an example:

CREATE OR REPLACE function returns_array()
RETURNS text[][] AS $$
return [['a"b','c,d'],['e\\f','g']];
$$ LANGUAGE plperl;

select returns_array();

and while it doesn't specifically mention SRFs it doesn't exclude them,
either.

The fix is fairly small (see attached) although I need to check with
some perlguts guru to see if I need to decrement a refcounter here or there.

Nobody has complained about it over the years, so I wonder if it should
be backpatched. It wouldn't change any working behaviour, just remove
the non-working property of some documented behaviour.

cheers

andrew

Attachments:

plperl-arrayfix.patchtext/x-patch; charset=iso-8859-1; name=plperl-arrayfix.patchDownload
Index: plperl.c
===================================================================
RCS file: /cvsroot/pgsql/src/pl/plperl/plperl.c,v
retrieving revision 1.150
diff -c -r1.150 plperl.c
*** plperl.c	11 Jun 2009 14:49:14 -0000	1.150
--- plperl.c	12 Sep 2009 16:46:40 -0000
***************
*** 1992,2001 ****
  	{
  		Datum		ret;
  		bool		isNull;
  
  		if (SvOK(sv))
  		{
! 			char	   *val = SvPV(sv, PL_na);
  
  			ret = InputFunctionCall(&prodesc->result_in_func, val,
  									prodesc->result_typioparam, -1);
--- 1992,2011 ----
  	{
  		Datum		ret;
  		bool		isNull;
+ 		SV		   *array_ret = NULL;
  
  		if (SvOK(sv))
  		{
! 			char	   *val;
! 
! 			if (prodesc->fn_retisarray && SvROK(sv) &&
! 				SvTYPE(SvRV(sv)) == SVt_PVAV)
! 			{
! 				array_ret = plperl_convert_to_pg_array(sv);
! 				sv = array_ret;
! 			}
! 
! 			val = SvPV(sv, PL_na);
  
  			ret = InputFunctionCall(&prodesc->result_in_func, val,
  									prodesc->result_typioparam, -1);
#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#1)
Re: plperl returning setof foo[]

Andrew Dunstan <andrew@dunslane.net> writes:

The fix is fairly small (see attached) although I need to check with
some perlguts guru to see if I need to decrement a refcounter here or there.

The array_ret variable seems a bit unnecessary, and declared well
outside the appropriate scope if it is necessary.

Nobody has complained about it over the years, so I wonder if it should
be backpatched. It wouldn't change any working behaviour, just remove
the non-working property of some documented behaviour.

AFAICT it just fails, so backpatching seems like a bug fix not a
behavioral change.

regards, tom lane

#3Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#2)
Re: plperl returning setof foo[]

Tom Lane wrote:

Nobody has complained about it over the years, so I wonder if it should
be backpatched. It wouldn't change any working behaviour, just remove
the non-working property of some documented behaviour.

AFAICT it just fails, so backpatching seems like a bug fix not a
behavioral change.

OK. will fix.

cheers

andrew

#4Abhijit Menon-Sen
ams@toroid.org
In reply to: Andrew Dunstan (#1)
1 attachment(s)
Re: plperl returning setof foo[]

At 2009-09-12 13:17:50 -0400, andrew@dunslane.net wrote:

I have just noticed, somewhat to my chagrin, that while in a plperl
function that returns an array type you can return a perl arrayref,
like this:

return [qw(a b c)];

if the function returns a setof an array type you cannot do this:

return_next [qw(a b c)];

Right. This was an unintentional omission on my part.

The fix is fairly small (see attached) although I need to check with
some perlguts guru to see if I need to decrement a refcounter here or
there.

Slightly simpler patch attached (and tested).

-- ams

Attachments:

plperl-arrayfix.difftext/x-diff; charset=us-asciiDownload
*** a/src/pl/plperl/plperl.c
--- b/src/pl/plperl/plperl.c
***************
*** 2021,2027 **** plperl_return_next(SV *sv)
  
  		if (SvOK(sv))
  		{
! 			char	   *val = SvPV(sv, PL_na);
  
  			ret = InputFunctionCall(&prodesc->result_in_func, val,
  									prodesc->result_typioparam, -1);
--- 2021,2035 ----
  
  		if (SvOK(sv))
  		{
! 			char	   *val;
! 
! 			if (prodesc->fn_retisarray && SvROK(sv) &&
! 				SvTYPE(SvRV(sv)) == SVt_PVAV)
! 			{
! 				sv = plperl_convert_to_pg_array(sv);
! 			}
! 
! 			val = SvPV(sv, PL_na);
  
  			ret = InputFunctionCall(&prodesc->result_in_func, val,
  									prodesc->result_typioparam, -1);
#5Andrew Dunstan
andrew@dunslane.net
In reply to: Abhijit Menon-Sen (#4)
Re: plperl returning setof foo[]

Abhijit Menon-Sen wrote:

The fix is fairly small (see attached) although I need to check with
some perlguts guru to see if I need to decrement a refcounter here or
there.

Slightly simpler patch attached (and tested).

Thanks. Committed.

cheers

andrew