Anyone want to fix plperl for null array elements?

Started by Tom Laneabout 20 years ago5 messages
#1Tom Lane
tgl@sss.pgh.pa.us

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

#2Michael Fuhr
mike@fuhr.org
In reply to: Tom Lane (#1)
Re: Anyone want to fix plperl for null array elements?

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

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#1)
Re: Anyone want to fix plperl for null array elements?

"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

#4Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#1)
Re: Anyone want to fix plperl for null array elements?

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

#5Andrew Dunstan
andrew@dunslane.net
In reply to: Michael Fuhr (#2)
Re: Anyone want to fix plperl for null array elements?

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}); " \
        "} "