Re: arrays as pl/perl input arguments [PATCH]

From: Alex Hunsaker <badalex(at)gmail(dot)com>
To: Alexey Klyukin <alexk(at)commandprompt(dot)com>
Cc: "David E(dot) Wheeler" <david(at)kineticode(dot)com>, pgsql-hackers(at)postgresql(dot)org, Andrew Dunstan <andrew(at)dunslane(dot)net>
Subject: Re: arrays as pl/perl input arguments [PATCH]
Date: 2011-02-04 01:29:59
Message-ID: AANLkTimxOze010uT-AGn=nFP7P_w5=DmUpm0xc5PWhWN@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon, Jan 31, 2011 at 01:34, Alexey Klyukin <alexk(at)commandprompt(dot)com> wrote:
> I've looked at the patch and added a test for arrays exceeding or equal maximum dimensions to check, whether the recursive function won't bring surprises there. I've also added check_stack_depth calls to both split_array and plperl_hash_from_tuple. Note that the regression fails currently due to the incorrect error reporting in
> PostgreSQL, per http://archives.postgresql.org/pgsql-hackers/2011-01/msg02888.php.
>
> The v5 is attached.

One thing I find odd is we allow for nested arrays, but not nested
composites. For example:
=> create type foo as (a int[]);
=> create type foofoo as (b foo);

=> create or replace function fa(foofoo[]) returns void as $$
my $foofoo_array = shift;
warn ref $foofoo_array->[0] || 'SCALAR';
warn ref $foofoo_array->[0]->{'b'} || 'SCALAR';
$$ language plperl;
=> select fa(ARRAY[ROW(ROW(ARRAY[1]))]::foofoo[]);
WARNING: HASH at line 3.
CONTEXT: PL/Perl function "fa"
WARNING: SCALAR at line 4.
CONTEXT: PL/Perl function "fa"

Why is foofoo.b a scalar but foofoo is a hash? This is not unique to
the patch, it how nested composites are handled in general. That is
if you passed in ROW(ROW()), the first ROW would be a hash while the
2nd row would be a scalar.

On the other end, the same is true when returning. If you try to
return a nested composite or array, the child better be a string as it
wont let you pass a hash:

=> create type foo as (a int[]);
=> create or replace function foo_in(foo) returns foo as $$ shift; $$
language plperl;
=> create or replace function foo_out() returns foo as $$ return
{'a'=>[1,2,3]}; $$ language plperl;

=> -- this works with the patch because we treat the reference as a string
=> select foo_in('("{1,2,3}")'::foo);
foo_in
-------------
("{1,2,3}")

=> select foo_out();
ERROR: array value must start with "{" or dimension information
CONTEXT: PL/Perl function "foo_out"
STATEMENT: SELECT foo_out();

-- also works as a straight string
=> create or replace function foo_out_str() returns foo as $$ return
{'a'=>'{1,2,3}'}; $$ language plperl;
=> select foo_out_str();
foo_out_str
-------------
("{1,2,3}")
(1 row)

Anyone object to fixing the above as part of this patch? That is
making plperl_(build_tuple_result, modify_tuple, return_next,
hash_from_tuple) handle array and hash (composite/row) types
consistently? And _that_ would be to recurse and turn them from/into
perl objects. Thoughts?

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Robert Haas 2011-02-04 01:36:32 Re: [HACKERS] Slow count(*) again...
Previous Message Robert Haas 2011-02-04 01:29:14 Re: [HACKERS] Slow count(*) again...