Re: multiple CREATE FUNCTION AS items for PLs

From: Hannu Krosing <hannu(at)krosing(dot)net>
To: Peter Eisentraut <peter_e(at)gmx(dot)net>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: multiple CREATE FUNCTION AS items for PLs
Date: 2012-12-28 12:09:03
Message-ID: 50DD8BDF.6030208@krosing.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 12/28/2012 09:15 AM, Peter Eisentraut wrote:
> On Mon, 2012-12-17 at 16:34 -0500, Peter Eisentraut wrote:
>> Yes, this would be a good solution for some applications, but the only
>> way I can think of to manage the compatibility issue is to invent some
>> function attribute system like
>>
>> CREATE FUNCTION ... OPTIONS (call_convention 'xyz')
> An alternative that has some amount of precedent in the Python world
> would be to use comment pragmas, like this:
>
> CREATE FUNCTION foo(a,b,c) AS $$
> # plpython: module
You mean something along the lines of how source encoding is
defined in http://www.python.org/dev/peps/pep-0263/ ?

Sounds like a plan :)
> import x
> from __future__ import nex_cool_feature
>
> def helper_function(x):
> ...
>
> def __pg_main__(a,b,c):
> defined function body here
>
> $$;
>
> The source code parser would look for this string on, say, the first two
> lines, and then decide which way to process the source text.
>
> This way we could get this done fairly easily without any new
> infrastructure outside the language handler.
>
I would still not name the defined function with any special static name
(like the samples __pg_main__) but have it default to the name of
PostgreSQL-defined function with possibility to override :

I don't much like the name __pg_main__ for the exported function what
about __call__ ?

__call__ is used when making an object callable in python, but is not
used at module
level so modules can't be callables in python.

Maybe just export the function with the same name as is defined in
CREATE FUNCTION ?

And in case we do want to override it, call it

CREATE FUNCTION foo(a int,b int, c text) AS $$
# plpython: module modulename
import x,y,z

def foo(a,b,c):
return a + b + c

def foo2(a,b,c):
return foo(a,b,int(c))

__call__ = foo2

$$ language plpythonu

If we always require the export using __call__ in new-style pl/python
functions we could
leave out the "# plpython: module " part altogether and just test for
__call__ in the compiled
modules namespace after trying to compile the source code as module and
re-compile
using current methods if this fails.

To make this fast also for old-style functions, we should store compiled
bytecode (.pyc) in
database as well, perhaps putting it in pg_proc.probin as a base64
encoded string (probin
is not used fro non-C functions) or adding a new bytea column
pg_proc.procode especially for this.

the module name could default to something more predictable, like
function name + argtypes
so that it would become exportable by other plpython functions

thus

CREATE FUNCTION foo(a int,b int, c text)

would create module

plpy.modules.foo_int4_int4_text

and

CREATE FUNCTION foo()

would become simply

plpy.modules.foo

in this case we could reuse the code so that if foo(a,b,c) from the previous example needs to be exported it would be just

CREATE FUNCTION foo(a int,b int, c int) AS $$
from plpy.modules.foo_int4_int4_text import foo2
__call__ = foo2
$$ language plpythonu

or even simpler

CREATE FUNCTION foo(a int,b int, c int) AS $$
from plpy.modules.foo_int4_int4_text import foo2 as __call__
$$ language plpythonu

-------------------------------
Hannu

------------
Hannu

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Stephen Frost 2012-12-28 14:00:50 Re: enhanced error fields
Previous Message Fabrízio de Royes Mello 2012-12-28 12:05:57 Re: Proposal: Store "timestamptz" of database creation on "pg_database"