Determining return type of polymorphic function

Started by Martijn van Oosterhoutover 20 years ago7 messages
#1Martijn van Oosterhout
kleptog@svana.org

[Please CC any replies so I don't have to follow them via the archives]

Hi,

I'm trying to create a set of types that are going to share the INPUT
and OUTPUT functions (written in C). For output you can determine the
type from the arguments, but for INPUT you can't. The prototype is
restricted (by CREATE TYPE) and you can't specify "anyelement" as the
return type because none of the arguments use it.

My current way around that is to create an alias to the function with
different names for each type, but get_fn_expr_rettype() doesn't appear
to be filled in anyway (fcinfo->flinfo->fn_expr == NULL).

What I'm trying to do now is use fcinfo->flinfo->fn_oid to lookup
pg_proc and get the return type from there, but something tells me
there must be an easier way.

Or to put it another way, if I define a function like:

CREATE FUNCTION myfunction(cstring, oid, integer)
RETURNS mytype AS 'mylib.so' LANGUAGE 'C';

How can I determine I'm supposed to return a "mytype"? I'm running 7.4
if it matters...

Thanks in advance,
--
Martijn van Oosterhout <kleptog@svana.org> http://svana.org/kleptog/

Show quoted text

Patent. n. Genius is 5% inspiration and 95% perspiration. A patent is a
tool for doing 5% of the work and then sitting around waiting for someone
else to do the other 95% so you can sue them.

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Martijn van Oosterhout (#1)
Re: Determining return type of polymorphic function

Martijn van Oosterhout <kleptog@svana.org> writes:

What I'm trying to do now is use fcinfo->flinfo->fn_oid to lookup
pg_proc and get the return type from there, but something tells me
there must be an easier way.

No, I think you're stuck. The internal calls for type I/O routines
don't set up fn_expr (since there is no expression tree).

One possibility, depending on your time horizon for this, is to change
the getTypeIOParam rules so that ordinary types get their own OID as
second argument.

regards, tom lane

#3Martijn van Oosterhout
kleptog@svana.org
In reply to: Tom Lane (#2)
Re: Determining return type of polymorphic function

[Please CC replies, thanks]

On Thu, Aug 11, 2005 at 02:17:30PM -0400, Tom Lane wrote:

Martijn van Oosterhout <kleptog@svana.org> writes:

What I'm trying to do now is use fcinfo->flinfo->fn_oid to lookup
pg_proc and get the return type from there, but something tells me
there must be an easier way.

No, I think you're stuck. The internal calls for type I/O routines
don't set up fn_expr (since there is no expression tree).

One possibility, depending on your time horizon for this, is to change
the getTypeIOParam rules so that ordinary types get their own OID as
second argument.

Hmm, I was thinking about that. While reading the documentation I was
thinking "surely they'd pass their own oid, giving zero would be silly"
so I was kind of surprised when I did get zero.

I was thinking of actually also storing the oid in the typelem field
but the docs imply this does something fancy with subscripting. I
havn't traced the code paths for that yet. At the very least I think it
would confuse anything looking for arrays. I also thought about typmod
(the third argument) but that seems to almost always be -1.

Would a patch to change the rules be accepted, or would it be
considered a unnecessary backward incompatable change?

Thanks in advance,
--
Martijn van Oosterhout <kleptog@svana.org> http://svana.org/kleptog/

Show quoted text

Patent. n. Genius is 5% inspiration and 95% perspiration. A patent is a
tool for doing 5% of the work and then sitting around waiting for someone
else to do the other 95% so you can sue them.

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Martijn van Oosterhout (#3)
Re: Determining return type of polymorphic function

Martijn van Oosterhout <kleptog@svana.org> writes:

I was thinking of actually also storing the oid in the typelem field
but the docs imply this does something fancy with subscripting.

Yeah, like enable it ;-). You can't do that unless you are some kind
of array type. typelem pointing at yourself would be particularly
bad news --- probably lead to infinite loops ...

Would a patch to change the rules be accepted, or would it be
considered a unnecessary backward incompatable change?

I wouldn't back-patch it, but it seems like something we could still put
in for 8.1.

regards, tom lane

#5Martijn van Oosterhout
kleptog@svana.org
In reply to: Tom Lane (#4)
Re: Determining return type of polymorphic function

On Thu, Aug 11, 2005 at 02:51:11PM -0400, Tom Lane wrote:

Would a patch to change the rules be accepted, or would it be
considered a unnecessary backward incompatable change?

I wouldn't back-patch it, but it seems like something we could still put
in for 8.1.

Ok, here's a patch (with documentation update). I checked the
regression tests (looked over, not run) but nothing there appears to
test this anyway. I looked through all the datatype input functions but
none of them even use the second argument except array and record types
and they're explicitly unchanged.

Note: the logic could be simplified if we could assume composite types
can't have a non-zero typelem. From looking at the code, I think it may
be assumed in places and I'm fairly sure it's non-sensical, but is it
explicitly forbidden?

I thought of writing a few simple tests but no language will accept
cstring arguments except C. It can be added if you think it's worth
regression testing.

Unless there are other comments I'll post this to pgsql-patches
later...

Have a nice day,
--
Martijn van Oosterhout <kleptog@svana.org> http://svana.org/kleptog/

Show quoted text

Patent. n. Genius is 5% inspiration and 95% perspiration. A patent is a
tool for doing 5% of the work and then sitting around waiting for someone
else to do the other 95% so you can sue them.

#6Martijn van Oosterhout
kleptog@svana.org
In reply to: Martijn van Oosterhout (#5)
1 attachment(s)
Re: [PATCH] Determining return type of polymorphic function

Forgot to attach it, oops.

On Fri, Aug 12, 2005 at 09:56:47AM +0200, Martijn van Oosterhout wrote:

Ok, here's a patch (with documentation update). I checked the
regression tests (looked over, not run) but nothing there appears to
test this anyway. I looked through all the datatype input functions but
none of them even use the second argument except array and record types
and they're explicitly unchanged.

Note: the logic could be simplified if we could assume composite types
can't have a non-zero typelem. From looking at the code, I think it may
be assumed in places and I'm fairly sure it's non-sensical, but is it
explicitly forbidden?

I thought of writing a few simple tests but no language will accept
cstring arguments except C. It can be added if you think it's worth
regression testing.

Unless there are other comments I'll post this to pgsql-patches
later...

--
Martijn van Oosterhout <kleptog@svana.org> http://svana.org/kleptog/

Show quoted text

Patent. n. Genius is 5% inspiration and 95% perspiration. A patent is a
tool for doing 5% of the work and then sitting around waiting for someone
else to do the other 95% so you can sue them.

Attachments:

typelem.patchtext/plain; charset=us-asciiDownload
Index: doc/src/sgml/ref/create_type.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/create_type.sgml,v
retrieving revision 1.57
diff -u -r1.57 create_type.sgml
--- doc/src/sgml/ref/create_type.sgml	14 Jul 2005 06:17:36 -0000	1.57
+++ doc/src/sgml/ref/create_type.sgml	12 Aug 2005 12:52:17 -0000
@@ -102,9 +102,8 @@
    declared as taking one argument of type <type>cstring</type>,
    or as taking three arguments of types
    <type>cstring</type>, <type>oid</type>, <type>integer</type>.
-   The first argument is the input text as a C string, the second
-   argument is the element type's OID in case this is an array type
-   (or the type's own OID for a composite type),
+   The first argument is the input text as a C string, the second argument is 
+   the OID of the type, except for arrays where it is the element type's OID
    and the third is the <literal>typmod</> of the destination column, if known
    (-1 will be passed if not).
    The input function must return a value of the data type itself.
Index: src/backend/utils/cache/lsyscache.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v
retrieving revision 1.116
diff -u -r1.116 lsyscache.c
--- src/backend/utils/cache/lsyscache.c	29 Aug 2004 05:06:50 -0000	1.116
+++ src/backend/utils/cache/lsyscache.c	12 Aug 2005 12:52:17 -0000
@@ -1220,12 +1220,14 @@
 
 	/*
 	 * Composite types get their own OID as parameter; array types get
-	 * their typelem as parameter; everybody else gets zero.
+	 * their typelem as parameter; everybody else gets their own oid.
 	 */
 	if (typeStruct->typtype == 'c')
 		return HeapTupleGetOid(typeTuple);
-	else
+	else if( typeStruct->typelem != 0 )
 		return typeStruct->typelem;
+	else
+		return HeapTupleGetOid(typeTuple);
 }
 
 /*
#7Tom Lane
tgl@sss.pgh.pa.us
In reply to: Martijn van Oosterhout (#6)
Re: [PATCH] Determining return type of polymorphic function

Martijn van Oosterhout <kleptog@svana.org> writes:

On Fri, Aug 12, 2005 at 09:56:47AM +0200, Martijn van Oosterhout wrote:

Ok, here's a patch (with documentation update). I checked the
regression tests (looked over, not run) but nothing there appears to
test this anyway. I looked through all the datatype input functions but
none of them even use the second argument except array and record types
and they're explicitly unchanged.

Note: the logic could be simplified if we could assume composite types
can't have a non-zero typelem.

They don't. Applied with that simplification.

regards, tom lane