Re: Allow SQL/plpgsql functions to accept record

From: Andrew Dunstan <andrew(at)dunslane(dot)net>
To: Jim Nasby <Jim(dot)Nasby(at)BlueTreble(dot)com>, "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>
Cc: "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Allow SQL/plpgsql functions to accept record
Date: 2015-04-22 16:20:06
Message-ID: 5537CA36.3070708@dunslane.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers


On 04/22/2015 11:29 AM, Jim Nasby wrote:
> On 4/20/15 2:04 PM, David G. Johnston wrote:
>>
>> ​SELECT (src.v).* FROM ( VALUES (ROW(1,2,3)) ) src (v)​;
>> ERROR: record type has not been registered
>>
>> While it may not be necessary to solve both problems I suspect they have
>> the same underlying root cause - specifically the separation of concerns
>> between the planner and the executor.
>
> I don't think they're related at all. C functions have the ability to
> accept a record, so the executor must be able to support it. It's just
> that SQL and plpgsql functions don't have that support. I suspect
> that's just because no one has gotten around to it.

Well, that's assuming everyone else thinks it would be a good idea.
Maybe they do, but I wouldn't assume it.

The answer in the past has been to use more dynamically typed languages
such as perl for which this problem is well suited.

There are actually several problems: first, given an arbitrary record
plpgsql has no easy and efficient way of finding out what field names it
has. Second, even if it has such knowledge it has no way of using it -
it's not like JavaScript where you can use a text value as a field name.
And third, it has no way of creating variables of the right type to hold
extracted values.

All of these could possibly be overcome, but it would not be a small
piece of work, I suspect. Given that plperl buys you all of that
already (just try this, for example) people might think it not worth
the extra trouble.

create function rkeys(record) returns text[] language plperl as $$
my $rec = shift; return [ keys %$rec ]; $$;
select unnest(rkeys(r)) from (select * from pg_class limit 1) r;

cheers

andrew

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Robert Haas 2015-04-22 16:21:39 Re: Custom/Foreign-Join-APIs (Re: [v9.5] Custom Plan API)
Previous Message Bruce Momjian 2015-04-22 16:16:43 Re: Turning off HOT/Cleanup sometimes