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
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" |