Re: actualised funcs typmod patch - Mailing list pgsql-hackers

From Dimitri Fontaine
Subject Re: actualised funcs typmod patch
Date
Msg-id 511CC3D1-3C56-47C4-8A10-73EC227BE970@hi-media.com
Whole thread Raw
In response to Re: actualised funcs typmod patch  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: actualised funcs typmod patch
List pgsql-hackers
Le 17 nov. 2009 à 20:33, Tom Lane a écrit :
>> We could to talk about it now. We are not hurry. But I would to see
>> some progress in this area in next two months. This patch is simple
>> and doesn't create any new rules or doesn't change behave.
>
> What do you mean it doesn't change the behavior?  It establishes a
> specific set of behaviors for functions with non-default typmods in
> their arguments.  If we just apply whatever was the easiest thing to
> implement, without any discussion, we are very likely to regret it
> later.
>
> It might be that what you've done is all fine, but I'd like some
> discussion and consensus on the issues.  Submitting an entirely
> documentation-free patch is not the way to establish consensus.

I'll try to help there, it's not really a review any more, but still it seems needed. Here's what I gather the specs of
Pavel'swork are by quick-reading through his patch: 
         /*
+          * Don't allow change of input typmodes. Any change should break
+          * stored casts in prepared plans.
+          */

The return type now can have a non -1 typmod given.

[implementation details of parameterTypmodes and allParameterTypmodes left out, not well understood yet, does seem to
bedetails rather than spec level things] 

+         if (rettypmod != resttypmod && rettypmod != -1)
+             ereport(ERROR,
+                     (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+              errmsg("return type mismatch in function declared to return %s",
+                     format_type_with_typemod(rettype, rettypmod)),
+                      errdetail("Actual return type is %s.",
+                                format_type_with_typemod(restype, resttypmod))));

So you need to return a decorated value I guess, or assign it to a retval which is of the right type, including typmod.
Declaringa retval text to handle a RETURNS varchar(15) won't do it. 


+         /* when typmodes are different, then foerce coercion too */
+         force_coerce = declared_typmod != -1 && declared_typmod != actual_typmod;

So if you declare typmods they are NOT part of the polymorphism (also per comment upthread) but you cannot change them
andthere's automatic coercion when only the typmod mismatches. I think that's what Tom wanted to avoid doing (because
itbreaks existing code assumptions and typmod coercion is not well defined). 

Here are some tests showing either the coercion of the argument (and failures to do it) or the return type typmod
invalidity:
+ ERROR:  cannot change parameter typmod of existing function

+ select typmodtest('a','bbbb');   -- outside plpgsql
+ ERROR:  value too long for type character varying(3)

+ select typmodtest('aaaa','bbb'); -- return value
+ ERROR:  value too long for type character varying(6)
+ CONTEXT:  PL/pgSQL function "typmodtest" while casting return value to function's return type


Then a great deal of changes that makes me cry in favor of having something human friendly around internal catalogs
representation,all this BKI stuff IIUC. 

So the bulk of it is supporting return typemod declaration. This expands to OUT types, which can be cool:

+ create or replace function typmodtest(out a numeric(5,2),out b numeric(5,2), out c numeric(5,2))


Hope this helps,
--
dim

PS: about the more than one anyelement type support in functions, I'd rather have a nice SQLish syntax around it. My
proposalwas sth like this: 

CREATE FUNCTION foo(a anyelement x, b anyelement x, c anyelement y)RETURNS anyelement y[]
AS $$
...
$$;

pgsql-hackers by date:

Previous
From: Alexey Klyukin
Date:
Subject: Re: plperl and inline functions -- first draft
Next
From: Robert Haas
Date:
Subject: Re: plpgsql: open for execute - add USING clause