Home Explore Blog CI



postgresql

64th chunk of `doc/src/sgml/plpgsql.sgml`
71c45e5f7c8f161ff6f9f474a1571cd1c887b53916f8bcda0000000100000fa1
 <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 $$
    &lt;&lt;fn&gt;&gt;
    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.

Title: Variable Substitution and Plan Caching in PL/pgSQL
Summary
This section describes variable substitution limitations in PL/pgSQL, noting it only works directly within SELECT, INSERT, UPDATE, DELETE, and related commands. For utility statements, dynamic SQL construction with EXECUTE is required. The section then details PL/pgSQL's plan caching mechanism. The interpreter creates an instruction tree during the first call. SQL expressions/commands are prepared using SPI_prepare upon first execution and reused in subsequent calls. Errors in unexecuted code paths are only detected upon execution. The SPI manager may cache execution plans, using parameter values for optimization or creating generic, parameter-independent plans for frequently executed statements.