Thread: pseudo-type record arguments for PL-functions

pseudo-type record arguments for PL-functions

From
Markus Schiltknecht
Date:
Hi,

I'm trying to write a PL/Python function which is to be called from a
rule. I'd need pass the OLD and NEW tuple records to the function.
Unfortunately that does not work: 'pl/python functions cannot take type
record'.

What I have figured out by reading the source code: OLD and NEW are
pseudo types (otherwise, pl/python would not have thrown that error)
(plpython.c:1088). During parsing of SQL function definitions the
arguments for the function are checked. In a comment I've read:
"Disallow pseudotypes in arguments" (pg_proc:546). I checked the other
PLs and found out, that no one can handle pseudo-arguments.

What exactly are pseudo types? Why are the OLD and NEW records of a rule
pseudo-types? Why can PLs not handle pseudo-types?

Or is it possible to write a C-function which takes the OLD and NEW
records of a rule as arguments? Is there an example of such a thing?

Regards

Markus




Re: pseudo-type record arguments for PL-functions

From
Tom Lane
Date:
Markus Schiltknecht <markus@bluegap.ch> writes:
> What exactly are pseudo types?

See
http://developer.postgresql.org/docs/postgres/extend-type-system.html

> Why can PLs not handle pseudo-types?

No one's done the work to figure out which ones are sensible to support
and then add the logic needed to support them.

In your particular case, the problem is that plpython isn't prepared to
handle rowtypes determined at runtime.  I'm not sure if the recently
submitted plpython patch fixes that or not.
        regards, tom lane


Re: pseudo-type record arguments for PL-functions

From
Thomas Hallgren
Date:
Tom Lane wrote:
>> Why can PLs not handle pseudo-types?
> 
> No one's done the work to figure out which ones are sensible to support
> and then add the logic needed to support them.
> 
PL/Java will handle the RECORD type correctly. I'm just finalizing a new, more flexible, 
type mapping implementation for PL/Java and it would be easy to add support for more pseudo 
types too. But what others would make sense?

Kind Regards,
Thomas Hallgren



Re: pseudo-type record arguments for PL-functions

From
Tom Lane
Date:
Thomas Hallgren <thomas@tada.se> writes:
> PL/Java will handle the RECORD type correctly. I'm just finalizing a new, more flexible, 
> type mapping implementation for PL/Java and it would be easy to add support for more pseudo 
> types too. But what others would make sense?

If you've got record/anyelement/anyarray support, you've probably pretty
much covered the bases.

Looking at the list (table 8-20), it strikes me that there's nothing
very pseudo about cstring anymore --- it could certainly be treated as
an ordinary datatype.  Not sure if there's any point in changing though.
        regards, tom lane


Re: pseudo-type record arguments for PL-functions

From
David Fetter
Date:
On Thu, May 04, 2006 at 09:02:02PM +0200, Thomas Hallgren wrote:
> Tom Lane wrote:
> > > Why can PLs not handle pseudo-types?
> >
> >No one's done the work to figure out which ones are sensible to
> >support and then add the logic needed to support them.
> >
> PL/Java will handle the RECORD type correctly. I'm just finalizing a
> new, more flexible, type mapping implementation for PL/Java and it
> would be easy to add support for more pseudo types too. But what
> others would make sense?

Ideally, some way to get all kinds of user-defined types.  DOMAINs,
too. :)

Cheers,
D
-- 
David Fetter <david@fetter.org> http://fetter.org/
phone: +1 415 235 3778        AIM: dfetter666                             Skype: davidfetter

Remember to vote!


Re: pseudo-type record arguments for PL-functions

From
Thomas Hallgren
Date:
David Fetter wrote:
> On Thu, May 04, 2006 at 09:02:02PM +0200, Thomas Hallgren wrote:
>   
>> Tom Lane wrote:
>>     
>>>> Why can PLs not handle pseudo-types?
>>>>         
>>> No one's done the work to figure out which ones are sensible to
>>> support and then add the logic needed to support them.
>>>
>>>       
>> PL/Java will handle the RECORD type correctly. I'm just finalizing a
>> new, more flexible, type mapping implementation for PL/Java and it
>> would be easy to add support for more pseudo types too. But what
>> others would make sense?
>>     
>
> Ideally, some way to get all kinds of user-defined types.  DOMAINs,
> too. :)
>
>   
OK, got them covered as well. Only thing that remain now is arrays. I 
have a hard time figuring out how to manage them. I'm looking at the 
arrayutils.c. The thing that makes me a bit confused is the 
ArrayMetaState. The functions obtain it using:
   my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;

which is fine if there's only one array parameter. What happens if I 
have two? And how do I declare a function that takes, say, an array of 
int's as a parameter (in SQL that is)?

I find very little information about how to write functions that deals 
with arrays. My only source of information right now is the 
arrayutils.c. Other pointers to docs and code are greatly appreciated.

Kind Regards,
Thomas Hallgren



Re: pseudo-type record arguments for PL-functions

From
Martijn van Oosterhout
Date:
On Sat, May 06, 2006 at 05:26:31PM +0200, Thomas Hallgren wrote:
> I find very little information about how to write functions that deals
> with arrays. My only source of information right now is the
> arrayutils.c. Other pointers to docs and code are greatly appreciated.

Looking at contrib/intarray/_int_op.c might help. It does something
like this:
       ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));

The file src/include/utils/array.h also seems to have many useful
functions.

Hope this helps,
--
Martijn van Oosterhout   <kleptog@svana.org>   http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.

Re: pseudo-type record arguments for PL-functions

From
Tom Lane
Date:
Thomas Hallgren <thomas@tada.se> writes:
> The thing that makes me a bit confused is the 
> ArrayMetaState. The functions obtain it using:

>     my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;

> which is fine if there's only one array parameter. What happens if I 
> have two?

Make a struct that can hold two ArrayMetaStates.  Or whatever else you
need.  What a C function keeps in fn_extra is its own affair.
        regards, tom lane


Re: pseudo-type record arguments for PL-functions

From
Thomas Hallgren
Date:
Tom Lane wrote:
> Make a struct that can hold two ArrayMetaStates.  Or whatever else you
> need.  What a C function keeps in fn_extra is its own affair.
>
>   
Yes, of course. I see that now. I was unaware that a function had an 
associated "user data". What's the semantics associated with the 
fn_extra? Does it retain its setting throughout a session (i.e. the 
lifetime of the backend process)?  PL/Java associates a structure with a 
function using a hash map lookup on the function Oid. Seems I could use 
the fn_extra and remove that map altogether.

Then again, there are times when I need to invalidate the associated 
structure of all java functions due to reload of jar files. Is there any 
way that I can list all functions for a specific language and get hold 
of their current setting of the fn_extra?

Regards,
Thomas Hallgren




Re: pseudo-type record arguments for PL-functions

From
Thomas Hallgren
Date:
Martijn van Oosterhout wrote:
> Looking at contrib/intarray/_int_op.c might help. It does something
> like this:
>
>         ArrayType  *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
>
> The file src/include/utils/array.h also seems to have many useful
> functions.
>
> Hope this helps,
>   
Yes, the intarray stuff was very helpful but also somewhat confusing. 
Why are there two ways of representing some of the array types? I mean, 
why is there an _int4 when you could just as well write int4[]? I'm 
probably missing the point altogether.

Regards,
Thomas Hallgren



Re: pseudo-type record arguments for PL-functions

From
Tom Lane
Date:
Thomas Hallgren <thomas@tada.se> writes:
> Yes, of course. I see that now. I was unaware that a function had an 
> associated "user data". What's the semantics associated with the 
> fn_extra? Does it retain its setting throughout a session (i.e. the 
> lifetime of the backend process)?

No, just for the query.  I'd advise using it only as a cache, although
set-returning functions sometimes use it to hold state associated with
successive rows of their result.
        regards, tom lane


Re: pseudo-type record arguments for PL-functions

From
James William Pye
Date:
On Sun, May 07, 2006 at 12:16:16AM +0200, Thomas Hallgren wrote:
> Yes, the intarray stuff was very helpful but also somewhat confusing. 
> Why are there two ways of representing some of the array types? I mean, 
> why is there an _int4 when you could just as well write int4[]? I'm 
> probably missing the point altogether.

FWICT, Prefixing a '_' is the convention used to make the array type's typname
unique. Being able to reference array types as _type is a "side effect".
(array types being actual rows in pg_type)


Re: pseudo-type record arguments for PL-functions

From
Tom Lane
Date:
James William Pye <pgsql@jwp.name> writes:
> On Sun, May 07, 2006 at 12:16:16AM +0200, Thomas Hallgren wrote:
>> Why are there two ways of representing some of the array types? I mean, 
>> why is there an _int4 when you could just as well write int4[]? I'm 
>> probably missing the point altogether.

> FWICT, Prefixing a '_' is the convention used to make the array type's typname
> unique. Being able to reference array types as _type is a "side effect".
> (array types being actual rows in pg_type)

There used to be some contexts where you *had* to write _foo instead of
foo[] because the grammar only allowed simple names and not the full
TypeName production.  I think we've fixed them all, but very likely
there are places in contrib still following the old convention.
        regards, tom lane