<literal>WHERE</literal> clause to make it refer to the table column.
But we did not have to qualify the reference to <literal>comment</literal>
as a target in the <literal>UPDATE</literal> list, because syntactically
that must be a column of <literal>users</literal>. We could write the same
function without depending on the <literal>variable_conflict</literal> setting
in this way:
<programlisting>
CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$
<<fn>>
DECLARE
curtime timestamp := now();
BEGIN
UPDATE users SET last_modified = fn.curtime, comment = stamp_user.comment
WHERE users.id = stamp_user.id;
END;
$$ LANGUAGE plpgsql;
</programlisting>
</para>
<para>
Variable substitution does not happen in a command string given
to <command>EXECUTE</command> or one of its variants. If you need to
insert a varying value into such a command, do so as part of
constructing the string value, or use <literal>USING</literal>, as illustrated in
<xref linkend="plpgsql-statements-executing-dyn"/>.
</para>
<para>
Variable substitution currently works only in <command>SELECT</command>,
<command>INSERT</command>, <command>UPDATE</command>,
<command>DELETE</command>, and commands containing one of
these (such as <command>EXPLAIN</command> and <command>CREATE TABLE
... AS SELECT</command>),
because the main SQL engine allows query parameters only in these
commands. To use a non-constant name or value in other statement
types (generically called utility statements), you must construct
the utility statement as a string and <command>EXECUTE</command> it.
</para>
</sect2>
<sect2 id="plpgsql-plan-caching">
<title>Plan Caching</title>
<para>
The <application>PL/pgSQL</application> interpreter parses the function's source
text and produces an internal binary instruction tree the first time the
function is called (within each session). The instruction tree
fully translates the
<application>PL/pgSQL</application> statement structure, but individual
<acronym>SQL</acronym> expressions and <acronym>SQL</acronym> commands
used in the function are not translated immediately.
</para>
<para>
<indexterm>
<primary>preparing a query</primary>
<secondary>in PL/pgSQL</secondary>
</indexterm>
As each expression and <acronym>SQL</acronym> command is first
executed in the function, the <application>PL/pgSQL</application> interpreter
parses and analyzes the command to create a prepared statement,
using the <acronym>SPI</acronym> manager's
<function>SPI_prepare</function> function.
Subsequent visits to that expression or command
reuse the prepared statement. Thus, a function with conditional code
paths that are seldom visited will never incur the overhead of
analyzing those commands that are never executed within the current
session. A disadvantage is that errors
in a specific expression or command cannot be detected until that
part of the function is reached in execution. (Trivial syntax
errors will be detected during the initial parsing pass, but
anything deeper will not be detected until execution.)
</para>
<para>
<application>PL/pgSQL</application> (or more precisely, the SPI manager) can
furthermore attempt to cache the execution plan associated with any
particular prepared statement. If a cached plan is not used, then
a fresh execution plan is generated on each visit to the statement,
and the current parameter values (that is, <application>PL/pgSQL</application>
variable values) can be used to optimize the selected plan. If the
statement has no parameters, or is executed many times, the SPI manager
will consider creating a <firstterm>generic</firstterm> plan that is not dependent
on specific parameter values, and caching that for re-use.