aboutsummaryrefslogtreecommitdiff
path: root/doc/src
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/sgml/filelist.sgml3
-rw-r--r--doc/src/sgml/plpython.sgml152
-rw-r--r--doc/src/sgml/programmer.sgml3
3 files changed, 156 insertions, 2 deletions
diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml
index 927a231d5aa..5881fb9183f 100644
--- a/doc/src/sgml/filelist.sgml
+++ b/doc/src/sgml/filelist.sgml
@@ -1,4 +1,4 @@
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/filelist.sgml,v 1.10 2001/05/08 19:14:52 momjian Exp $ -->
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/filelist.sgml,v 1.11 2001/05/12 17:49:32 petere Exp $ -->
<!entity history SYSTEM "history.sgml">
<!entity info SYSTEM "info.sgml">
@@ -75,6 +75,7 @@
<!entity xoper SYSTEM "xoper.sgml">
<!entity xtypes SYSTEM "xtypes.sgml">
<!entity plperl SYSTEM "plperl.sgml">
+<!entity plpython SYSTEM "plpython.sgml">
<!entity plsql SYSTEM "plsql.sgml">
<!entity pltcl SYSTEM "pltcl.sgml">
diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml
new file mode 100644
index 00000000000..f96f085afd7
--- /dev/null
+++ b/doc/src/sgml/plpython.sgml
@@ -0,0 +1,152 @@
+<!-- $Header: /cvsroot/pgsql/doc/src/sgml/plpython.sgml,v 1.1 2001/05/12 17:49:32 petere Exp $ -->
+
+<chapter id="plpython">
+ <title>PL/Python - Python Procedural Language</title>
+
+ <note>
+ <para>
+ This chapter is not fully developed yet.
+ </para>
+ </note>
+
+ <sect1 id="plpython-install">
+ <title>Installation</title>
+
+ <para>
+ ... needs to be worked out.
+ </para>
+ </sect1>
+
+ <sect1 id="plpython-using">
+ <title>Using</title>
+
+ <para>
+ There are sample functions in
+ <filename>plpython_function.sql</filename>. 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';
+</programlisting>
+
+ gets transformed into
+
+<programlisting>
+def __plpython_procedure_myfunc_23456():
+ return args[0]
+</programlisting>
+
+ where 23456 is the Oid of the function.
+ </para>
+
+ <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.
+ </para>
+
+ <para>
+ PostgreSQL function variables are available in the global
+ <varname>args</varname> list. In the <function>myfunc</function>
+ example, args[0] contains whatever was passed in as the text
+ argument. For <literal>myfunc2(text, int4)</literal>, args[0]
+ would contain the text variable and args[1] the int4 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. When the function is used in a
+ trigger, the triggers tuples are in TD["new"] and/or TD["old"]
+ depending on the trigger event. Return 'None' or "OK" from the
+ python function to indicate the tuple is unmodified, "SKIP" to
+ abort the event, or "MODIFIED" to indicate you've modified the
+ tuple. If the trigger was called with arguments they are available
+ in TD["args"][0] to TD["args"][(n -1)]
+ </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.
+ </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.error("msg")</literal>,
+ <literal>plpy.fatal("msg")</literal>,
+ <literal>plpy.debug("msg")</literal>, and
+ <literal>plpy.notice("msg")</literal>. They are mostly equivalent
+ to calling <literal>elog(<replaceable>LEVEL</>, "msg")</literal>,
+ where <replaceable>LEVEL</> is DEBUG, ERROR, FATAL or NOTICE.
+ <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>.
+ </para>
+
+ <para>
+ Additionally, the plpy 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
+ list or dictionary object. The result object can be accessed by
+ 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.
+
+<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
+<programlisting>
+foo = rv[i]["my_field"]
+</programlisting>
+ 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.
+<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.
+<programlisting>
+rv = plpy.execute(plan, [ "name" ], 5)
+</programlisting>
+ The limit argument is optional in the call to
+ <function>plpy.execute</function>.
+ </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
+ home message is if you do
+<programlisting>
+plan = plpy.prepare("SOME QUERY")
+plan = plpy.prepare("SOME OTHER QUERY")
+</programlisting>
+ you are leaking memory, as I know of no way to free a saved plan.
+ The alternative of using unsaved plans it even more painful (for
+ me).
+ </para>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/programmer.sgml b/doc/src/sgml/programmer.sgml
index af899eceee2..f4013a52132 100644
--- a/doc/src/sgml/programmer.sgml
+++ b/doc/src/sgml/programmer.sgml
@@ -1,5 +1,5 @@
<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/Attic/programmer.sgml,v 1.36 2001/05/08 19:14:52 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/Attic/programmer.sgml,v 1.37 2001/05/12 17:49:32 petere Exp $
PostgreSQL Programmer's Guide.
-->
@@ -84,6 +84,7 @@ Disable it until we put in some info.
&plsql;
&pltcl;
&plperl;
+ &plpython;
</part>
<![%single-book;[