-<!-- $PostgreSQL: pgsql/doc/src/sgml/plpython.sgml,v 1.44 2010/01/22 15:45:15 petere Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/plpython.sgml,v 1.45 2010/03/13 20:55:05 petere Exp $ -->
<chapter id="plpython">
<title>PL/Python - Python Procedural Language</title>
<title>PL/Python Functions</title>
<para>
- Functions in PL/Python are declared via the standard <xref
- linkend="sql-createfunction" endterm="sql-createfunction-title">
- syntax:
+ Functions in PL/Python are declared via the
+ standard <xref linkend="sql-createfunction"> syntax:
<programlisting>
CREATE FUNCTION <replaceable>funcname</replaceable> (<replaceable>argument-list</replaceable>)
<para>
The body of a function is simply a Python script. When the function
- is called, its arguments are passed as elements of the array
- <varname>args[]</varname>; named arguments are also passed as ordinary
- variables to the Python script. The result is returned from the Python code
+ is called, its arguments are passed as elements of the list
+ <varname>args</varname>; named arguments are also passed as
+ ordinary variables to the Python script. Use of named arguments is
+ usually more readable. The result is returned from the Python code
in the usual way, with <literal>return</literal> or
- <literal>yield</literal> (in case of a result-set statement).
+ <literal>yield</literal> (in case of a result-set statement). If
+ you do not provide a return value, Python returns the default
+ <symbol>None</symbol>. <application>PL/Python</application> translates
+ Python's <symbol>None</symbol> into the SQL null value.
</para>
<para>
<productname>PostgreSQL</productname>.
</para>
- <para>
- The <productname>PostgreSQL</> function parameters are available in
- the global <varname>args</varname> list. In the
- <function>pymax</function> example, <varname>args[0]</varname> contains
- whatever was passed in as the first argument and
- <varname>args[1]</varname> contains the second argument's
- value. Alternatively, one can use named parameters as shown in the example
- above. Use of named parameters is usually more readable.
- </para>
-
<para>
The arguments are set as global variables. Because of the scoping
rules of Python, this has the subtle consequence that an argument
PL/Python. It is better to treat the function parameters as
read-only.
</para>
+ </sect1>
+
+ <sect1>
+ <title>Data Values</title>
+ <para>
+ Generally speaking, the aim of PL/Python is to provide
+ a <quote>natural</quote> mapping between the PostgreSQL and the
+ Python worlds. This informs the data mapping rules described
+ below.
+ </para>
+
+ <sect2>
+ <title>Data Type Mapping</title>
+ <para>
+ Function arguments are converted from their PostgreSQL type to a
+ corresponding Python type:
+ <itemizedlist>
+ <listitem>
+ <para>
+ PostgreSQL <type>boolean</type> is converted to Python <type>bool</type>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ PostgreSQL <type>smallint</type> and <type>int</type> are
+ converted to Python <type>int</type>.
+ PostgreSQL <type>bigint</type> is converted
+ to <type>long</type> in Python 2 and to <type>int</type> in
+ Python 3.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ PostgreSQL <type>real</type>, <type>double</type>,
+ and <type>numeric</type> are converted to
+ Python <type>float</type>. Note that for
+ the <type>numeric</type> this loses information and can lead to
+ incorrect results. This might be fixed in a future
+ release.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ PostgreSQL <type>bytea</type> is converted to
+ Python <type>str</type> in Python 2 and to <type>bytes</type>
+ in Python 3. In Python 2, the string should be treated as a
+ byte sequence without any character encoding.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ All other data types, including the PostgreSQL character string
+ types, are converted to a Python <type>str</type>. In Python
+ 2, this string will be in the PostgreSQL server encoding; in
+ Python 3, it will be a Unicode string like all strings.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For nonscalar data types, see below.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Function return values are converted to the declared PostgreSQL
+ return data type as follows:
+ <itemizedlist>
+ <listitem>
+ <para>
+ When the PostgreSQL return type is <type>boolean</type>, the
+ return value will be evaluated for truth according to the
+ <emphasis>Python</emphasis> rules. That is, 0 and empty string
+ are false, but notably <literal>'f'</literal> is true.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When the PostgreSQL return type is <type>bytea</type>, the
+ return value will be converted to a string (Python 2) or bytes
+ (Python 3) using the respective Python builtins, with the
+ result being converted <type>bytea</type>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For all other PostgreSQL return types, the returned Python
+ value is converted to a string using the Python
+ builtin <literal>str</literal>, and the result is passed to the
+ input function of the PostgreSQL data type.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ For nonscalar data types, see below.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Note that logical mismatches between the declared PostgreSQL
+ return type and the Python data type of the actual return object
+ are not flagged; the value will be converted in any case.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Null, None</title>
<para>
If an SQL null value<indexterm><primary>null value</primary><secondary
sortas="PL/Python">PL/Python</secondary></indexterm> is passed to a
function, return the value <symbol>None</symbol>. This can be done whether the
function is strict or not.
</para>
+ </sect2>
+ <sect2>
+ <title>Arrays, Lists</title>
<para>
SQL array values are passed into PL/Python as a Python list. To
return an SQL array value out of a PL/Python function, return a
(1 row)
</programlisting>
</para>
+ </sect2>
+ <sect2>
+ <title>Composite Types</title>
<para>
Composite-type arguments are passed to the function as Python mappings. The
element names of the mapping are the attribute names of the composite type.
</varlistentry>
</variablelist>
</para>
+ </sect2>
- <para>
- If you do not provide a return value, Python returns the default
- <symbol>None</symbol>. <application>PL/Python</application> translates
- Python's <symbol>None</symbol> into the SQL null value.
- </para>
-
+ <sect2>
+ <title>Set-Returning Functions</title>
<para>
A <application>PL/Python</application> function can also return sets of
scalar or composite types. There are several ways to achieve this because
<warning>
<para>
- Currently, due to Python
+ Due to Python
<ulink url="http://bugs.python.org/issue1483133">bug #1483133</ulink>,
some debug versions of Python 2.4
(configured and compiled with option <literal>--with-pydebug</literal>)
</varlistentry>
</variablelist>
</para>
+ </sect2>
+ </sect1>
+ <sect1 id="plpython-sharing">
+ <title>Sharing Data</title>
<para>
The global dictionary <varname>SD</varname> is available to store
data between function calls. This variable is private static data.
<para>
When a function is used as a trigger, the dictionary
- <literal>TD</literal> contains trigger-related values.
- <literal>TD["event"]</> contains
- the event as a string (<literal>INSERT</>, <literal>UPDATE</>,
- <literal>DELETE</>, <literal>TRUNCATE</>, or <literal>UNKNOWN</>).
- <literal>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</>.
- For a row-level trigger, the trigger
- rows are in <literal>TD["new"]</> and/or <literal>TD["old"]</>
- depending on the trigger event.
- <literal>TD["name"]</> contains the trigger name,
- <literal>TD["table_name"]</> contains the name of the table on which the trigger occurred,
- <literal>TD["table_schema"]</> contains the schema of the table on which the trigger occurred,
- and <literal>TD["relid"]</> contains the OID of the table on
- which the trigger occurred. If the <command>CREATE TRIGGER</> command
- included arguments, they are available in <literal>TD["args"][0]</> to
- <literal>TD["args"][<replaceable>n</>-1]</>.
+ <literal>TD</literal> contains trigger-related values:
+ <variablelist>
+ <varlistentry>
+ <term><literal>TD["event"]</></term>
+ <listitem>
+ <para>
+ contains the event as a string:
+ <literal>INSERT</>, <literal>UPDATE</>,
+ <literal>DELETE</>, <literal>TRUNCATE</>,
+ or <literal>UNKNOWN</>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["when"]</></term>
+ <listitem>
+ <para>
+ contains one of <literal>BEFORE</>, <literal>AFTER</>,
+ or <literal>UNKNOWN</>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["level"]</></term>
+ <listitem>
+ <para>
+ contains one of <literal>ROW</>,
+ <literal>STATEMENT</>, or <literal>UNKNOWN</>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["new"]</></term>
+ <term><literal>TD["old"]</></term>
+ <listitem>
+ <para>
+ For a row-level trigger, one or both of these fields contain
+ the respective trigger rows, depending on the trigger event.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["name"]</></term>
+ <listitem>
+ <para>
+ contains the trigger name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["table_name"]</></term>
+ <listitem>
+ <para>
+ contains the name of the table on which the trigger occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["table_schema"]</></term>
+ <listitem>
+ <para>
+ contains the schema of the table on which the trigger occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["relid"]</></term>
+ <listitem>
+ <para>
+ contains the OID of the table on which the trigger occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["args"]</></term>
+ <listitem>
+ <para>
+ If the <command>CREATE TRIGGER</> command
+ included arguments, they are available in <literal>TD["args"][0]</> to
+ <literal>TD["args"][<replaceable>n</>-1]</>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</para>
<para>
The PL/Python language module automatically imports a Python module
called <literal>plpy</literal>. The functions and constants in
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(<replaceable>msg</>)</literal>,
- <literal>plpy.log(<replaceable>msg</>)</literal>,
- <literal>plpy.info(<replaceable>msg</>)</literal>,
- <literal>plpy.notice(<replaceable>msg</>)</literal>,
- <literal>plpy.warning(<replaceable>msg</>)</literal>,
- <literal>plpy.error(<replaceable>msg</>)</literal>, and
- <literal>plpy.fatal(<replaceable>msg</>)</literal>.<indexterm><primary>elog</><secondary>in PL/Python</></indexterm>
- <function>plpy.error</function> and
- <function>plpy.fatal</function> actually raise a Python exception
- which, if uncaught, propagates out to the calling query, causing
- the current transaction or subtransaction to be aborted.
- <literal>raise plpy.ERROR(<replaceable>msg</>)</literal> and
- <literal>raise plpy.FATAL(<replaceable>msg</>)</literal> are
- equivalent to calling
- <function>plpy.error</function> and
- <function>plpy.fatal</function>, respectively.
- The other functions only generate messages of different
- priority levels.
- Whether messages of a particular priority are reported to the client,
- written to the server log, or both is controlled by the
- <xref linkend="guc-log-min-messages"> and
- <xref linkend="guc-client-min-messages"> configuration
- variables. See <xref linkend="runtime-config"> for more information.
+ <literal>plpy.<replaceable>foo</replaceable></literal>.
</para>
<para>
- Additionally, the <literal>plpy</literal> module provides two
+ 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
In order to make effective use of this across function calls
one needs to use one of the persistent storage dictionaries
<literal>SD</literal> or <literal>GD</literal> (see
- <xref linkend="plpython-funcs">). For example:
+ <xref linkend="plpython-sharing">). For example:
<programlisting>
CREATE FUNCTION usesavedplan() RETURNS trigger AS $$
if SD.has_key("plan"):
</para>
</sect1>
-<![IGNORE[
- <!-- NOT CURRENTLY SUPPORTED -->
-
- <sect1 id="plpython-trusted">
- <title>Restricted Environment</title>
-
+ <sect1 id="plpython-util">
+ <title>Utility Functions</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:
- <literal>array</>, <literal>bisect</>, <literal>binascii</>,
- <literal>calendar</>, <literal>cmath</>, <literal>codecs</>,
- <literal>errno</>, <literal>marshal</>, <literal>math</>, <literal>md5</>,
- <literal>mpz</>, <literal>operator</>, <literal>pcre</>,
- <literal>pickle</>, <literal>random</>, <literal>re</>, <literal>regex</>,
- <literal>sre</>, <literal>sha</>, <literal>string</>, <literal>StringIO</>,
- <literal>struct</>, <literal>time</>, <literal>whrandom</>, and
- <literal>zlib</>.
+ The <literal>plpy</literal> module also provides the functions
+ <literal>plpy.debug(<replaceable>msg</>)</literal>,
+ <literal>plpy.log(<replaceable>msg</>)</literal>,
+ <literal>plpy.info(<replaceable>msg</>)</literal>,
+ <literal>plpy.notice(<replaceable>msg</>)</literal>,
+ <literal>plpy.warning(<replaceable>msg</>)</literal>,
+ <literal>plpy.error(<replaceable>msg</>)</literal>, and
+ <literal>plpy.fatal(<replaceable>msg</>)</literal>.<indexterm><primary>elog</><secondary>in PL/Python</></indexterm>
+ <function>plpy.error</function> and
+ <function>plpy.fatal</function> actually raise a Python exception
+ which, if uncaught, propagates out to the calling query, causing
+ the current transaction or subtransaction to be aborted.
+ <literal>raise plpy.ERROR(<replaceable>msg</>)</literal> and
+ <literal>raise plpy.FATAL(<replaceable>msg</>)</literal> are
+ equivalent to calling
+ <function>plpy.error</function> and
+ <function>plpy.fatal</function>, respectively.
+ The other functions only generate messages of different
+ priority levels.
+ Whether messages of a particular priority are reported to the client,
+ written to the server log, or both is controlled by the
+ <xref linkend="guc-log-min-messages"> and
+ <xref linkend="guc-client-min-messages"> configuration
+ variables. See <xref linkend="runtime-config"> for more information.
</para>
</sect1>
-]]>
-
</chapter>