From: | James Pye <lists(at)jwp(dot)name> |
---|---|
To: | PG Hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | WIP: plpython3 |
Date: | 2009-07-23 22:23:40 |
Message-ID: | FF3A61B6-D1EB-4057-9071-7415FE03DBDA@jwp.name |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
http://github.com/jwp/postgresql-plpython3/tree/plpython3 [branch
name: plpython3]
[src/pl/plpython3] (Yeah, I'm going to try to move it to
git.postgresql.org soon-ish)
In a recent thread[1], Peter said:
That also means that maintaining a separate, parallel code base
for a Python 3 variant can only be acceptable if it gives major
advantages.
Here are the features that I plan/hope to implement before submitting
any patch:
* Native Typing [Python types that represent Postgres types]
* Reworked function structure (Python modules, not function fragments)
* Improved SQL interfaces (prepared statement objects[2])
* Better SRF support(?) (uses iterators, will support composites,
vpc & mat)
* Direct function calls (to other Postgres functions)
* IST support (with xact(): ...)
* Full tracebacks for Python exceptions(CONTEXT support)
* Cached bytecode (presuming a "procache" attributes patch would be
acceptable[3])
The first two features are why a new PL should be incorporated.
Native typing alone is that desirable because it allows for Postgres
type semantics to be retained inside Python. Using conversion for some
types--the existing solution in plpython--may not be desirable due to
potential inconsistencies in value. A notable example is that Python's
datetime.timedelta cannot support interval's month field. And from a
performance perspective, creating Python objects representing a
parameter is approximately the cost of allocating memory for a Python
object and datumCopy.
The second feature, function structure, is actually new to the PL.
Originally PL/Py took a pl/python-like approach to triggers and
functions. *Currently*, I want to change procedures to be Python
modules with specific entry points used to handle an event. Mere
invocation: "main". Or, a trigger event: "before_insert",
"after_insert", "before_update", etc.
So, a regular function might look like:
CREATE OR REPLACE FUNCTION foo(int) RETURNS int LANGUAGE plpython3u AS
$python$
import Postgres
def main(i):
return i
$python$;
Despite the signature repetition, this is an improvement for the user
and the developer. The user now has an explicit initialization section
that is common to Python(it's a module). The PL developer no longer
needs to munge the source, and can work with common Python APIs to
manage and introspect the procedure's module(...thinking: procedure
settings..).
A trigger function might look like:
CREATE OR REPLACE FUNCTION trig() RETURNS TRIGGER LANGUAGE plpython3u AS
$python$
import Postgres
def check(i):
...
def before_insert(new):
...
def before_update(new, old):
# The default action is for the manipulation to occur,
# so users must explicitly raise FilterEvent in order to
# stop a row from being inserted, updated, deleted.
if check(new["column_name"]):
raise StopEvent()
def after_delete(old):
...
$python$;
Thoughts? [...it still has a *long* ways to go =]
[1] http://archives.postgresql.org/pgsql-hackers/2009-05/msg01376.php
[2] http://python.projects.postgresql.org/docs/0.9/driver.html#prepared-statement-interface-points
[3] http://archives.postgresql.org/pgsql-hackers/2006-05/
msg01160.php (I think a new column would be wise)
From | Date | Subject | |
---|---|---|---|
Next Message | David E. Wheeler | 2009-07-23 22:29:24 | Re: When is a record NULL? |
Previous Message | David E. Wheeler | 2009-07-23 22:19:36 | When is a record NULL? |