Thread: pseudo-type record arguments for PL-functions
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
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
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
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
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!
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
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.
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
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
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
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
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)
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