Thread: Anyone want to fix plperl for null array elements?

Anyone want to fix plperl for null array elements?

From
Tom Lane
Date:
I think plperl should be fixed to translate undef to NULL when returning
an array, but currently it translates to an empty string:

pl_regression=# CREATE OR REPLACE function returns_array() returns text[] as $$
pl_regression$# return ['a,b','c"d',undef,'e-f']; $$ LANGUAGE plperl;
CREATE FUNCTION
pl_regression=# select returns_array();    returns_array
-----------------------{"a,b","c\"d","",e-f}
(1 row)

There might be some problems going in the other direction, too;
I haven't tried.  Anybody feeling eager to fix this?
        regards, tom lane


Re: Anyone want to fix plperl for null array elements?

From
Michael Fuhr
Date:
On Thu, Nov 17, 2005 at 08:41:51PM -0500, Tom Lane wrote:
> I think plperl should be fixed to translate undef to NULL when returning
> an array, but currently it translates to an empty string:

I'll take a look at this if nobody else steps up.  It might just
be a minor change to this part of plperl.c:

210     "    else " \
211     "    { " \
212     "      my $str = qq($elem); " \
213     "      $str =~ s/([\"\\\\])/\\\\$1/g; " \
214     "      $res .= qq(\"$str\"); " \
215     "    } " \

> There might be some problems going in the other direction, too;
> I haven't tried.  Anybody feeling eager to fix this?

Does the current implementation provide automatic conversion to a
Perl array for inbound values?  Unless I'm missing something that
entire problem might still need to be solved.

-- 
Michael Fuhr


Re: Anyone want to fix plperl for null array elements?

From
"Andrew Dunstan"
Date:
Tom Lane said:
> I think plperl should be fixed to translate undef to NULL when
> returning an array, but currently it translates to an empty string:
>
> pl_regression=# CREATE OR REPLACE function returns_array() returns
> text[] as $$ pl_regression$# return ['a,b','c"d',undef,'e-f']; $$
> LANGUAGE plperl; CREATE FUNCTION
> pl_regression=# select returns_array();
>     returns_array
> -----------------------
> {"a,b","c\"d","",e-f}
> (1 row)
>
> There might be some problems going in the other direction, too;
> I haven't tried.  Anybody feeling eager to fix this?
>

I will fix this tomorrow - it's about a 4 line fix. I've missed the details
- we're just using an unquoted NULL in array literals?

cheers

andrew




Re: Anyone want to fix plperl for null array elements?

From
Tom Lane
Date:
"Andrew Dunstan" <andrew@dunslane.net> writes:
> I will fix this tomorrow - it's about a 4 line fix. I've missed the details
> - we're just using an unquoted NULL in array literals?

Right.  Case-insensitive, double-quote it if you want the literal string
instead.

regression=# select array[1,null,3];  array    
------------{1,NULL,3}
(1 row)

        regards, tom lane


Re: Anyone want to fix plperl for null array elements?

From
Andrew Dunstan
Date:

Michael Fuhr wrote:

>On Thu, Nov 17, 2005 at 08:41:51PM -0500, Tom Lane wrote:
>  
>
>>I think plperl should be fixed to translate undef to NULL when returning
>>an array, but currently it translates to an empty string:
>>    
>>
>
>I'll take a look at this if nobody else steps up.  It might just
>be a minor change to this part of plperl.c:
>
>210     "    else " \
>211     "    { " \
>212     "      my $str = qq($elem); " \
>213     "      $str =~ s/([\"\\\\])/\\\\$1/g; " \
>214     "      $res .= qq(\"$str\"); " \
>215     "    } " \
>
>  
>

Yeah.

I have the fix below which I will apply shortly. Demo:

perltest=# CREATE OR REPLACE function returns_array() returns text[] as $$
perltest$# return ['a,b','c"d',undef,'e-f']; $$ LANGUAGE plperl;
CREATE FUNCTION
perltest=# select returns_array();     returns_array      ------------------------{"a,b","c\"d",NULL,e-f}


>>There might be some problems going in the other direction, too;
>>I haven't tried.  Anybody feeling eager to fix this?
>>    
>>
>
>Does the current implementation provide automatic conversion to a
>Perl array for inbound values?  Unless I'm missing something that
>entire problem might still need to be solved.
>
>  
>

Correct, we get the string representation, which is ugly. We certainly 
want to change that for 8.2 so we get an arrayref. And this makes it 
more urgent. demo:

perltest=# create or replace function dump_array(text[]) returns text 
language plperlu as $$ use Data::Dumper; return Dumper(\@_); $$;
CREATE FUNCTION
perltest=# select dump_array(ARRAY(select datname from pg_database));                               dump_array
                     
 
---------------------------------------------------------------------------$VAR1 = [
'{postgres,perltest,template1,template0}'      ];
 


cheers

andrew

Index: plperl.c
===================================================================
RCS file: /cvsroot/pgsql/src/pl/plperl/plperl.c,v
retrieving revision 1.94
diff -c -r1.94 plperl.c
*** plperl.c    18 Oct 2005 17:13:14 -0000      1.94
--- plperl.c    18 Nov 2005 13:13:31 -0000
***************
*** 207,218 ****       "    { " \       "      $res .= _plperl_to_pg_array($elem); " \       "    } " \
!       "    else " \       "    { " \       "      my $str = qq($elem); " \       "      $str =~
s/([\"\\\\])/\\\\$1/g;" \       "      $res .= qq(\"$str\"); " \       "    } " \       "  } " \       "  return
qq({$res});" \       "} "
 
--- 207,222 ----       "    { " \       "      $res .= _plperl_to_pg_array($elem); " \       "    } " \
!       "    elsif (defined($elem)) " \       "    { " \       "      my $str = qq($elem); " \       "      $str =~
s/([\"\\\\])/\\\\$1/g;" \       "      $res .= qq(\"$str\"); " \       "    } " \
 
+       "    else " \
+       "    { "\
+       "      $res .= 'NULL' ; " \
+       "    } "\       "  } " \       "  return qq({$res}); " \       "} "