possible for example to debug query execution results
using <literal>plpy.debug(rv)</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
The result object can be modified.
</para>
<para>
Note that calling <literal>plpy.execute</literal> will cause the entire
result set to be read into memory. Only use that function when you are
sure that the result set will be relatively small. If you don't want to
risk excessive memory usage when fetching large results,
use <literal>plpy.cursor</literal> rather
than <literal>plpy.execute</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>plpy.<function>prepare</function>(<replaceable>query</replaceable> [, <replaceable>argtypes</replaceable>])</literal></term>
<term><literal>plpy.<function>execute</function>(<replaceable>plan</replaceable> [, <replaceable>arguments</replaceable> [, <replaceable>limit</replaceable>]])</literal></term>
<listitem>
<para>
<indexterm><primary>preparing a query</primary><secondary>in PL/Python</secondary></indexterm>
<function>plpy.prepare</function> prepares the execution plan for a
query. It is called with a query string and a list of parameter types,
if you have parameter references in the query. For example:
<programlisting>
plan = plpy.prepare("SELECT last_name FROM my_users WHERE first_name = $1", ["text"])
</programlisting>
<literal>text</literal> is the type of the variable you will be passing
for <literal>$1</literal>. The second argument is optional if you don't
want to pass any parameters to the query.
</para>
<para>
After preparing a statement, you use a variant of the
function <function>plpy.execute</function> to run it:
<programlisting>
rv = plpy.execute(plan, ["name"], 5)
</programlisting>
Pass the plan as the first argument (instead of the query string), and a
list of values to substitute into the query as the second argument. The
second argument is optional if the query does not expect any parameters.
The third argument is the optional row limit as before.
</para>
<para>
Alternatively, you can call the <function>execute</function> method on
the plan object:
<programlisting>
rv = plan.execute(["name"], 5)
</programlisting>
</para>
<para>
Query parameters and result row fields are converted between PostgreSQL
and Python data types as described in <xref linkend="plpython-data"/>.
</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. 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-sharing"/>). For example:
<programlisting>
CREATE FUNCTION usesavedplan() RETURNS trigger AS $$
if "plan" in SD:
plan = SD["plan"]
else:
plan = plpy.prepare("SELECT 1")
SD["plan"] = plan
# rest of function
$$ LANGUAGE plpython3u;
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>plpy.<function>cursor</function>(<replaceable>query</replaceable>)</literal></term>
<term><literal>plpy.<function>cursor</function>(<replaceable>plan</replaceable> [, <replaceable>arguments</replaceable>])</literal></term>
<listitem>
<para>
The <literal>plpy.cursor</literal> function accepts the same arguments
as <literal>plpy.execute</literal> (except for the row limit) and returns
a cursor object, which allows you to process large result sets in smaller
chunks. As with <literal>plpy.execute</literal>, either a query string
or