Re: polymorphic arguments and return type for PL/pgSQL - Mailing list pgsql-patches

From Joe Conway
Subject Re: polymorphic arguments and return type for PL/pgSQL
Date
Msg-id 3F00592D.1050409@joeconway.com
Whole thread Raw
In response to Re: polymorphic arguments and return type for PL/pgSQL  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: polymorphic arguments and return type for PL/pgSQL  (Joe Conway <mail@joeconway.com>)
List pgsql-patches
Tom Lane wrote:
> Joe Conway <mail@joeconway.com> writes:
>>The attached patch enables PL/pgSQL functions (but not triggers) to
>>accept and return polymorphic types. It is careful to return false from
>>func_up_to_date() if any of the polymorphic types change from
>>call-to-call.
>
> I don't think you can usefully do it that way.  Suppose the same
> function is being invoked in two places in a query, with two different
> actual argument types at the two spots.  Won't this setup result in
> dropping and rebuilding the function cache twice per row?

Actually, no. Every compile of the function gets added to a linked list,
and a subsequent call checks the list for a compiled version matching
the funcoid and argument/return types; from plpgsql_call_handler():

<snip>
if (func == NULL)
{
   /*
    * Check if we already compiled this function for another caller
    */
   for (func = compiled_functions; func != NULL; func = func->next)
   {
     if (funcOid == func->fn_oid && func_up_to_date(func, fcinfo))
     break;
   }

   /*
    * If not, do so and add it to the compiled ones
    */
   if (func == NULL)
   {
     func = plpgsql_compile(funcOid,
               isTrigger ? T_TRIGGER : T_FUNCTION,
               fcinfo);
     func->next = compiled_functions;
     compiled_functions = func;
   }
</snip>

> You've really got to arrange for there to be a separate function cache
> entry for each set of argument types --- in other words, the actual arg
> types have to be part of the cache key.

See above; it already does that. Actually, that's not even new, but it
did work out nice for this purpose.

> (It might be time to change the  cache lookup into a hashtable instead of
> a simple linear list search...)

I could do that if you want, but do you really think it's worth it? How
long does a linked list have to get before a hash table starts to be a
win (this is something I've always wondered about anyway)?

>>It also falls back to the pg_proc declared types if the
>>caller didn't setup the FuncExpr node.
>
> This will result in "plpgsql functions cannot return type anyarray"
> which is at best misleading.  It'd be better to have a specific error
> message, say "could not determine actual return type for polymorphic
> function %s".

OK, that's an easy change.

Thanks,

Joe




pgsql-patches by date:

Previous
From: Tom Lane
Date:
Subject: Re: Patch for adding DATACUBE operator
Next
From: sumit
Date:
Subject: Re: Patch for adding DATACUBE operator