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




























--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to