<command>GET DIAGNOSTICS</command>
command. The second and any subsequent lines refer to calling functions
further up the call stack. For example:
<programlisting>
CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$
BEGIN
RETURN inner_func();
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION inner_func() RETURNS integer AS $$
DECLARE
stack text;
BEGIN
GET DIAGNOSTICS stack = PG_CONTEXT;
RAISE NOTICE E'--- Call Stack ---\n%', stack;
RETURN 1;
END;
$$ LANGUAGE plpgsql;
SELECT outer_func();
NOTICE: --- Call Stack ---
PL/pgSQL function inner_func() line 5 at GET DIAGNOSTICS
PL/pgSQL function outer_func() line 3 at RETURN
CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN
outer_func
------------
1
(1 row)
</programlisting>
</para>
<para>
<literal>GET STACKED DIAGNOSTICS ... PG_EXCEPTION_CONTEXT</literal>
returns the same sort of stack trace, but describing the location
at which an error was detected, rather than the current location.
</para>
</sect2>
</sect1>
<sect1 id="plpgsql-cursors">
<title>Cursors</title>
<indexterm zone="plpgsql-cursors">
<primary>cursor</primary>
<secondary>in PL/pgSQL</secondary>
</indexterm>
<para>
Rather than executing a whole query at once, it is possible to set
up a <firstterm>cursor</firstterm> that encapsulates the query, and then read
the query result a few rows at a time. One reason for doing this is
to avoid memory overrun when the result contains a large number of
rows. (However, <application>PL/pgSQL</application> users do not normally need
to worry about that, since <literal>FOR</literal> loops automatically use a cursor
internally to avoid memory problems.) A more interesting usage is to
return a reference to a cursor that a function has created, allowing the
caller to read the rows. This provides an efficient way to return
large row sets from functions.
</para>
<sect2 id="plpgsql-cursor-declarations">
<title>Declaring Cursor Variables</title>
<para>
All access to cursors in <application>PL/pgSQL</application> goes through
cursor variables, which are always of the special data type
<type>refcursor</type>. One way to create a cursor variable
is just to declare it as a variable of type <type>refcursor</type>.
Another way is to use the cursor declaration syntax,
which in general is:
<synopsis>
<replaceable>name</replaceable> <optional> <optional> NO </optional> SCROLL </optional> CURSOR <optional> ( <replaceable>arguments</replaceable> ) </optional> FOR <replaceable>query</replaceable>;
</synopsis>
(<literal>FOR</literal> can be replaced by <literal>IS</literal> for
<productname>Oracle</productname> compatibility.)
If <literal>SCROLL</literal> is specified, the cursor will be capable of
scrolling backward; if <literal>NO SCROLL</literal> is specified, backward
fetches will be rejected; if neither specification appears, it is
query-dependent whether backward fetches will be allowed.
<replaceable>arguments</replaceable>, if specified, is a
comma-separated list of pairs <literal><replaceable>name</replaceable>
<replaceable>datatype</replaceable></literal> that define names to be
replaced by parameter values in the given query. The actual
values to substitute for these names will be specified later,
when the cursor is opened.
</para>
<para>
Some examples:
<programlisting>
DECLARE
curs1 refcursor;
curs2 CURSOR FOR SELECT * FROM tenk1;
curs3 CURSOR (key integer) FOR SELECT * FROM tenk1 WHERE unique1 = key;
</programlisting>
All three of these variables have the data type <type>refcursor</type>,
but the first can be used with any query, while the second has
a fully specified query already <firstterm>bound</firstterm> to it, and the last
has a parameterized query bound to it. (<literal>key</literal> will be