Home Explore Blog CI



postgresql

62th chunk of `doc/src/sgml/plpgsql.sgml`
92ef3fdb525f88a834d8f085350046b42458cfc7b6b4a68d0000000100000fa0
 syntactically permissible.  As an extreme case, consider
    this example of poor programming style:
<programlisting>
INSERT INTO foo (foo) VALUES (foo(foo));
</programlisting>
    The first occurrence of <literal>foo</literal> must syntactically be a table
    name, so it will not be substituted, even if the function has a variable
    named <literal>foo</literal>.  The second occurrence must be the name of a
    column of that table, so it will not be substituted either.  Likewise
    the third occurrence must be a function name, so it also will not be
    substituted for.  Only the last occurrence is a candidate to be a
    reference to a variable of the <application>PL/pgSQL</application>
    function.
   </para>

   <para>
    Another way to understand this is that variable substitution can only
    insert data values into an SQL command; it cannot dynamically change which
    database objects are referenced by the command.  (If you want to do
    that, you must build a command string dynamically, as explained in
    <xref linkend="plpgsql-statements-executing-dyn"/>.)
   </para>

   <para>
    Since the names of variables are syntactically no different from the names
    of table columns, there can be ambiguity in statements that also refer to
    tables: is a given name meant to refer to a table column, or a variable?
    Let's change the previous example to
<programlisting>
INSERT INTO dest (col) SELECT foo + bar FROM src;
</programlisting>
    Here, <literal>dest</literal> and <literal>src</literal> must be table names, and
    <literal>col</literal> must be a column of <literal>dest</literal>, but <literal>foo</literal>
    and <literal>bar</literal> might reasonably be either variables of the function
    or columns of <literal>src</literal>.
   </para>

   <para>
    By default, <application>PL/pgSQL</application> will report an error if a name
    in an SQL statement could refer to either a variable or a table column.
    You can fix such a problem by renaming the variable or column,
    or by qualifying the ambiguous reference, or by telling
    <application>PL/pgSQL</application> which interpretation to prefer.
   </para>

   <para>
    The simplest solution is to rename the variable or column.
    A common coding rule is to use a
    different naming convention for <application>PL/pgSQL</application>
    variables than you use for column names.  For example,
    if you consistently name function variables
    <literal>v_<replaceable>something</replaceable></literal> while none of your
    column names start with <literal>v_</literal>, no conflicts will occur.
   </para>

   <para>
    Alternatively you can qualify ambiguous references to make them clear.
    In the above example, <literal>src.foo</literal> would be an unambiguous reference
    to the table column.  To create an unambiguous reference to a variable,
    declare it in a labeled block and use the block's label
    (see <xref linkend="plpgsql-structure"/>).  For example,
<programlisting>
&lt;&lt;block&gt;&gt;
DECLARE
    foo int;
BEGIN
    foo := ...;
    INSERT INTO dest (col) SELECT block.foo + bar FROM src;
</programlisting>
    Here <literal>block.foo</literal> means the variable even if there is a column
    <literal>foo</literal> in <literal>src</literal>.  Function parameters, as well as
    special variables such as <literal>FOUND</literal>, can be qualified by the
    function's name, because they are implicitly declared in an outer block
    labeled with the function's name.
   </para>

   <para>
    Sometimes it is impractical to fix all the ambiguous references in a
    large body of <application>PL/pgSQL</application> code.  In such cases you can
    specify that <application>PL/pgSQL</application> should resolve ambiguous references
    as the variable (which is compatible with <application>PL/pgSQL</application>'s
    behavior before <productname>PostgreSQL</productname> 9.0), or as the
    table column (which is compatible with some

Title: PL/pgSQL Variable Substitution and Ambiguity Resolution
Summary
This section delves into how PL/pgSQL substitutes variables in SQL statements, clarifying that it primarily inserts data values and cannot dynamically alter database object references. It uses examples to show how PL/pgSQL determines which identifiers are variables versus table/column names. The section highlights the potential for ambiguity when variable names clash with column names. It discusses strategies for resolving such ambiguities, including renaming variables or columns, using qualified references (e.g., src.foo for a column or block.foo for a variable), and leveraging labeled blocks. It also mentions the option to configure PL/pgSQL to prefer either variables or table columns in ambiguous cases, although this is generally discouraged in favor of clearer coding practices.