aboutsummaryrefslogtreecommitdiff
path: root/doc/src/sgml/plpython.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/plpython.sgml')
-rw-r--r--doc/src/sgml/plpython.sgml245
1 files changed, 126 insertions, 119 deletions
diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml
index 2e38a5c7917..110c2a826e5 100644
--- a/doc/src/sgml/plpython.sgml
+++ b/doc/src/sgml/plpython.sgml
@@ -1,4 +1,4 @@
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/plpython.sgml,v 1.10 2002/03/22 19:20:18 petere Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/plpython.sgml,v 1.11 2002/09/18 20:09:32 petere Exp $ -->
<chapter id="plpython">
<title>PL/Python - Python Procedural Language</title>
@@ -6,90 +6,42 @@
<indexterm zone="plpython"><primary>PL/Python</></>
<indexterm zone="plpython"><primary>Python</></>
- <sect1 id="plpython-intro">
- <title>Introduction</title>
+ <para>
+ The <application>PL/Python</application> procedural language allows
+ <productname>PostgreSQL</productname> functions to be written in the
+ <ulink url="http://www.python.org">Python</ulink> language.
+ </para>
- <para>
- The <application>PL/Python</application> procedural language allows
- <productname>PostgreSQL</productname> functions to be written in
- the <ulink url="http://www.python.org">Python</ulink> language.
- </para>
+ <para>
+ To install PL/Python in a particular database, use
+ <literal>createlang plpython <replaceable>dbname</></literal>.
+ </para>
+ <note>
<para>
- The current version of <application>PL/Python</application>
- functions as a trusted language only; access to the file system and
- other local resources is disabled. Specifically,
- <application>PL/Python</application> uses the Python restricted
- execution environment, further restricts it to prevent the use of
- the file <function>open</> call, and allows only modules from a
- specific list to be imported. Presently, that list includes:
- array, bisect, binascii, calendar, cmath, codecs, errno, marshal,
- math, md5, mpz, operator, pcre, pickle, random, re, regex, sre,
- sha, string, StringIO, struct, time, whrandom, and zlib.
+ Users of source packages must specially enable the build of
+ PL/Python during the installation process (refer to the
+ installation instructions for more information). Users of binary
+ packages might find PL/Python in a separate subpackage.
</para>
+ </note>
- <para>
- In the current version, any database error encountered while
- running a <application>PL/Python</application> function will result
- in the immediate termination of that function by the server. It is
- not possible to trap error conditions using Python <literal>try
- ... catch</literal> constructs. For example, a syntax error in an
- SQL statement passed to the <literal>plpy.execute()</literal> call
- will terminate the function. This behavior may be changed in a
- future release.
- </para>
- </sect1>
-
- <sect1 id="plpython-install">
- <title>Installation</title>
-
- <para>
- To build PL/Python, the <option>--with-python</option> option needs
- to be specified when running <filename>configure</filename>. If
- after building and installing you have a file called
- <filename>plpython.so</filename> (possibly a different extension),
- then everything went well. Otherwise you should have seen a notice
- like this flying by:
-<screen>
-*** Cannot build PL/Python because libpython is not a shared library.
-*** You might have to rebuild your Python installation. Refer to
-*** the documentation for details.
-</screen>
- That means you have to rebuild (part of) your Python installation
- to supply this shared library.
- </para>
-
- <para>
- The catch is that the Python distribution or the Python maintainers
- do not provide any direct way to do this. The closest thing we can
- offer you is the information in <ulink
- url="http://www.python.org/doc/FAQ.html#3.30">Python FAQ
- 3.30</ulink>. On some operating systems you don't really have to
- build a shared library, but then you will have to convince the
- PostgreSQL build system of this. Consult the
- <filename>Makefile</filename> in the
- <filename>src/pl/plpython</filename> directory for details.
- </para>
- </sect1>
-
- <sect1 id="plpython-using">
- <title>Using PL/Python</title>
+ <sect1 id="plpython-funcs">
+ <title>PL/Python Functions</title>
<para>
- There are sample functions in
- <filename>plpython_function.sql</filename>. The Python code you
- write gets transformed into a function. E.g.,
+ The Python code you write gets transformed into a function. E.g.,
<programlisting>
-CREATE FUNCTION myfunc(text) RETURNS text AS
-'return args[0]'
-LANGUAGE 'plpython';
+CREATE FUNCTION myfunc(text) RETURNS text
+ AS 'return args[0]'
+ LANGUAGE 'plpython';
</programlisting>
gets transformed into
<programlisting>
def __plpython_procedure_myfunc_23456():
- return args[0]
+ return args[0]
</programlisting>
where 23456 is the OID of the function.
@@ -98,51 +50,68 @@ def __plpython_procedure_myfunc_23456():
<para>
If you do not provide a return value, Python returns the default
<symbol>None</symbol> which may or may not be what you want. The
- language module translates Python's None into SQL NULL.
+ language module translates Python's <symbol>None</symbol> into the
+ SQL null value.
</para>
<para>
- <productname>PostgreSQL</> function variables are available in the global
- <varname>args</varname> list. In the <function>myfunc</function>
- example, <varname>args[0]</> contains whatever was passed in as the text
- argument. For <literal>myfunc2(text, integer)</literal>, <varname>args[0]</>
- would contain the <type>text</type> variable and <varname>args[1]</varname> the <type>integer</type> variable.
+ The <productname>PostgreSQL</> function parameters are available in
+ the global <varname>args</varname> list. In the
+ <function>myfunc</function> example, <varname>args[0]</> contains
+ whatever was passed in as the text argument. For
+ <literal>myfunc2(text, integer)</literal>, <varname>args[0]</>
+ would contain the <type>text</type> variable and
+ <varname>args[1]</varname> the <type>integer</type> variable.
</para>
<para>
- The global dictionary SD is available to store data between
- function calls. This variable is private static data. The global
- dictionary GD is public data, available to all python functions
- within a backend. Use with care.
+ The global dictionary <varname>SD</varname> is available to store
+ data between function calls. This variable is private static data.
+ The global dictionary <varname>GD</varname> is public data,
+ available to all Python functions within a session. Use with care.
</para>
<para>
Each function gets its own restricted execution object in the
Python interpreter, so that global data and function arguments from
<function>myfunc</function> are not available to
- <function>myfunc2</function>. The exception is the data in the GD
- dictionary, as mentioned above.
+ <function>myfunc2</function>. The exception is the data in the
+ <varname>GD</varname> dictionary, as mentioned above.
</para>
+ </sect1>
+
+ <sect1 id="plpython-trigger">
+ <title>Trigger Functions</title>
<para>
- When a function is used in a trigger, the dictionary TD contains
- transaction related values. The trigger tuples are in <literal>TD["new"]</>
- and/or <literal>TD["old"]</> depending on the trigger event. <literal>TD["event"]</>
- contains the event as a string (<literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>, or
- <literal>UNKNOWN</>). TD["when"] contains one of (<literal>BEFORE</>, <literal>AFTER</>, or
- <literal>UNKNOWN</>). <literal>TD["level"]</> contains one of <literal>ROW</>, <literal>STATEMENT</>, or
- <literal>UNKNOWN</>. <literal>TD["name"]</> contains the trigger name, and <literal>TD["relid"]</>
- contains the relation id of the table on which the trigger occurred.
- If the trigger was called with arguments they are available
- in <literal>TD["args"][0]</> to <literal>TD["args"][(n -1)]</>.
+ When a function is used in a trigger, the dictionary
+ <literal>TD</literal> contains trigger-related values. The trigger
+ rows are in <literal>TD["new"]</> and/or <literal>TD["old"]</>
+ depending on the trigger event. <literal>TD["event"]</> contains
+ the event as a string (<literal>INSERT</>, <literal>UPDATE</>,
+ <literal>DELETE</>, or <literal>UNKNOWN</>).
+ <literal>TD["when"]</> contains one of <literal>BEFORE</>,
+ <literal>AFTER</>, and <literal>UNKNOWN</>.
+ <literal>TD["level"]</> contains one of <literal>ROW</>,
+ <literal>STATEMENT</>, and <literal>UNKNOWN</>.
+ <literal>TD["name"]</> contains the trigger name, and
+ <literal>TD["relid"]</> contains the relation ID of the table on
+ which the trigger occurred. If the trigger was called with
+ arguments they are available in <literal>TD["args"][0]</> to
+ <literal>TD["args"][(n-1)]</>.
</para>
<para>
- If the trigger <quote>when</quote> is <literal>BEFORE</>, you may return <literal>None</literal> or <literal>"OK"</literal>
- from the Python function to indicate the tuple is unmodified,
- <literal>"SKIP"</> to abort the event, or <literal>"MODIFIED"</> to indicate you've
- modified the tuple.
+ If the <literal>TD["when"]</literal> is <literal>BEFORE</>, you may
+ return <literal>None</literal> or <literal>"OK"</literal> from the
+ Python function to indicate the row is unmodified,
+ <literal>"SKIP"</> to abort the event, or <literal>"MODIFIED"</> to
+ indicate you've modified the row.
</para>
+ </sect1>
+
+ <sect1 id="plpython-database">
+ <title>Database Access</title>
<para>
The PL/Python language module automatically imports a Python module
@@ -150,54 +119,64 @@ def __plpython_procedure_myfunc_23456():
this module are available to you in the Python code as
<literal>plpy.<replaceable>foo</replaceable></literal>. At present
<literal>plpy</literal> implements the functions
- <literal>plpy.debug("msg")</literal>,
+ <literal>plpy.debug("msg")</literal>,
<literal>plpy.log("msg")</literal>,
<literal>plpy.info("msg")</literal>,
<literal>plpy.notice("msg")</literal>,
<literal>plpy.warning("msg")</literal>,
<literal>plpy.error("msg")</literal>, and
<literal>plpy.fatal("msg")</literal>. They are mostly equivalent
- to calling <literal>elog(<replaceable>LEVEL</>, "msg")</literal>.
- <function>plpy.error</function> and <function>plpy.fatal</function>
- actually raise a Python exception which, if uncaught, causes the
- PL/Python module to call <literal>elog(ERROR, msg)</literal> when
- the function handler returns from the Python interpreter. Long
- jumping out of the Python interpreter is probably not good.
- <literal>raise plpy.ERROR("msg")</literal> and <literal>raise
+ to calling <literal>elog(<replaceable>LEVEL</>, "msg")</literal>
+ from C code. <function>plpy.error</function> and
+ <function>plpy.fatal</function> actually raise a Python exception
+ which, if uncaught, causes the PL/Python module to call
+ <literal>elog(ERROR, msg)</literal> when the function handler
+ returns from the Python interpreter. Long-jumping out of the
+ Python interpreter is probably not good. <literal>raise
+ plpy.ERROR("msg")</literal> and <literal>raise
plpy.FATAL("msg")</literal> are equivalent to calling
- <function>plpy.error</function> or <function>plpy.fatal</function>.
+ <function>plpy.error</function> and
+ <function>plpy.fatal</function>, respectively.
</para>
<para>
- Additionally, the <literal>plpy</literal> module provides two functions called
- <function>execute</function> and <function>prepare</function>.
- Calling <function>plpy.execute</function> with a query string, and
- an optional limit argument, causes that query to be run, and the
- result returned in a result object. The result object emulates a
+ Additionally, the <literal>plpy</literal> module provides two
+ functions called <function>execute</function> and
+ <function>prepare</function>. Calling
+ <function>plpy.execute</function> with a query string and an
+ optional limit argument causes that query to be run and the result
+ to be returned in a result object. The result object emulates a
list or dictionary object. The result object can be accessed by
- row number, and field name. It has these additional methods:
+ row number and field name. It has these additional methods:
<function>nrows()</function> which returns the number of rows
returned by the query, and <function>status</function> which is the
<function>SPI_exec</function> return variable. The result object
can be modified.
+ </para>
+ <para>
+ For example,
<programlisting>
rv = plpy.execute("SELECT * FROM my_table", 5)
</programlisting>
- returns up to 5 rows from my_table. Ff my_table has a column
- my_field it would be accessed as
+ returns up to 5 rows from <literal>my_table</literal>. If
+ <literal>my_table</literal> has a column
+ <literal>my_field</literal>, it would be accessed as
<programlisting>
foo = rv[i]["my_field"]
</programlisting>
+ </para>
+
+ <para>
The second function <function>plpy.prepare</function> is called
- with a query string, and a list of argument types if you have bind
- variables in the query.
+ with a query string and a list of argument types if you have bind
+ variables in the query. For example:
<programlisting>
plan = plpy.prepare("SELECT last_name FROM my_users WHERE first_name = $1", [ "text" ])
</programlisting>
- text is the type of the variable you will be passing as $1. After
- preparing you use the function <function>plpy.execute</function> to
- run it.
+ <literal>text</literal> is the type of the variable you will be
+ passing as <literal>$1</literal>. After preparing a statement, you
+ use the function <function>plpy.execute</function> to run it:
<programlisting>
rv = plpy.execute(plan, [ "name" ], 5)
</programlisting>
@@ -206,6 +185,17 @@ rv = plpy.execute(plan, [ "name" ], 5)
</para>
<para>
+ In the current version, any database error encountered while
+ running a <application>PL/Python</application> function will result
+ in the immediate termination of that function by the server; it is
+ not possible to trap error conditions using Python <literal>try
+ ... catch</literal> constructs. For example, a syntax error in an
+ SQL statement passed to the <literal>plpy.execute()</literal> call
+ will terminate the function. This behavior may be changed in a
+ future release.
+ </para>
+
+ <para>
When you prepare a plan using the PL/Python module it is
automatically saved. Read the SPI documentation (<xref
linkend="spi">) for a description of what this means. The take
@@ -220,4 +210,21 @@ plan = plpy.prepare("SOME OTHER QUERY")
</para>
</sect1>
+ <sect1 id="plpython-trusted">
+ <title>Restricted Environment</title>
+
+ <para>
+ The current version of <application>PL/Python</application>
+ functions as a trusted language only; access to the file system and
+ other local resources is disabled. Specifically,
+ <application>PL/Python</application> uses the Python restricted
+ execution environment, further restricts it to prevent the use of
+ the file <function>open</> call, and allows only modules from a
+ specific list to be imported. Presently, that list includes:
+ array, bisect, binascii, calendar, cmath, codecs, errno, marshal,
+ math, md5, mpz, operator, pcre, pickle, random, re, regex, sre,
+ sha, string, StringIO, struct, time, whrandom, and zlib.
+ </para>
+ </sect1>
+
</chapter>