I looked over the v2 patch. Parts of it seem like improvements but
other parts definitely don't. In particular, I thought you introduced
a great deal of confusion in 43.5.2 (Executing a Command with No Result).
The statement that you can write a non-result-returning SQL command as-is
is true in general, and ought not be confused with the question of whether
you can insert variable values into it. Also, starting with a spongy
definition of "utility command" and then contrasting with that does not
seem to me to add clarity.
I attach a v3 that I like better, although there's room to disagree
about that. I've always felt that the separation between 43.5.2 and
43.5.3 was rather artificial --- it's okay I guess for describing
how to handle command output, but we end up with considerable
duplication when it comes to describing how to insert values into a
command. It's tempting to try re-splitting it to separate optimizable
from non-optimizable statements; but maybe that'd just end with
different duplication.
regards, tom lane
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml
index 9242c54329..aa868b4191 100644
--- a/doc/src/sgml/plpgsql.sgml
+++ b/doc/src/sgml/plpgsql.sgml
@@ -894,7 +894,7 @@ SELECT <replaceable>expression</replaceable>
</synopsis>
to the main SQL engine. While forming the <command>SELECT</command> command,
any occurrences of <application>PL/pgSQL</application> variable names
- are replaced by parameters, as discussed in detail in
+ are replaced by query parameters, as discussed in detail in
<xref linkend="plpgsql-var-subst"/>.
This allows the query plan for the <command>SELECT</command> to
be prepared just once and then reused for subsequent
@@ -1004,20 +1004,32 @@ complex_array[n].realpart = 12.3;
</para>
<para>
- Any <application>PL/pgSQL</application> variable name appearing
- in the command text is treated as a parameter, and then the
+ In optimizable SQL commands (<command>INSERT</command>,
+ <command>UPDATE</command>, and <command>DELETE</command>),
+ any <application>PL/pgSQL</application> variable name appearing
+ in the command text is replaced by a query parameter, and then the
current value of the variable is provided as the parameter value
at run time. This is exactly like the processing described earlier
for expressions; for details see <xref linkend="plpgsql-var-subst"/>.
</para>
<para>
- When executing a SQL command in this way,
+ When executing an optimizable SQL command in this way,
<application>PL/pgSQL</application> may cache and re-use the execution
plan for the command, as discussed in
<xref linkend="plpgsql-plan-caching"/>.
</para>
+ <para>
+ Non-optimizable SQL commands (also called utility commands) are not
+ capable of accepting query parameters. So automatic substitution
+ of <application>PL/pgSQL</application> variables does not work in such
+ commands. To include non-constant text in a utility command executed
+ from <application>PL/pgSQL</application>, you must build the utility
+ command as a string and then <command>EXECUTE</command> it, as
+ discussed in <xref linkend="plpgsql-statements-executing-dyn"/>.
+ </para>
+
<para>
Sometimes it is useful to evaluate an expression or <command>SELECT</command>
query but discard the result, for example when calling a function
@@ -1095,11 +1107,11 @@ DELETE ... RETURNING <replaceable>expressions</replaceable> INTO <optional>STRIC
record/row fields.
<application>PL/pgSQL</application> variables will be
substituted into the rest of the query, and the plan is cached,
- just as described above for commands that do not return rows.
+ just as described above for optimizable commands that do not return rows.
This works for <command>SELECT</command>,
<command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command> with
- <literal>RETURNING</literal>, and utility commands that return row-set
- results (such as <command>EXPLAIN</command>).
+ <literal>RETURNING</literal>, and certain utility commands
+ that return row sets, such as <command>EXPLAIN</command>.
Except for the <literal>INTO</literal> clause, the SQL command is the same
as it would be written outside <application>PL/pgSQL</application>.
</para>
@@ -2567,7 +2579,7 @@ $$ LANGUAGE plpgsql;
</para>
<para>
- <application>PL/pgSQL</application> variables are substituted into the query text,
+ <application>PL/pgSQL</application> variables are replaced by query parameters,
and the query plan is cached for possible re-use, as discussed in
detail in <xref linkend="plpgsql-var-subst"/> and
<xref linkend="plpgsql-plan-caching"/>.
@@ -4643,7 +4655,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch();
SQL statements and expressions within a <application>PL/pgSQL</application> function
can refer to variables and parameters of the function. Behind the scenes,
<application>PL/pgSQL</application> substitutes query parameters for such references.
- Parameters will only be substituted in places where a parameter or
+ Query parameters will only be substituted in places where a parameter or
column reference is syntactically allowed. As an extreme case, consider
this example of poor programming style:
<programlisting>
@@ -4657,13 +4669,6 @@ INSERT INTO foo (foo) VALUES (foo);
variable.
</para>
- <note>
- <para>
- <productname>PostgreSQL</productname> versions before 9.0 would try
- to substitute the variable in all three cases, leading to syntax errors.
- </para>
- </note>
-
<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
@@ -5314,11 +5319,12 @@ HINT: Make sure the query returns the exact list of columns.
<listitem>
<para>
If a name used in a SQL command could be either a column name of a
- table or a reference to a variable of the function,
- <application>PL/SQL</application> treats it as a column name. This corresponds
- to <application>PL/pgSQL</application>'s
+ table used in the command or a reference to a variable of the function,
+ <application>PL/SQL</application> treats it as a column name.
+ By default, <application>PL/pgSQL</application> will treat it as a
+ variable, but you can specify
<literal>plpgsql.variable_conflict</literal> = <literal>use_column</literal>
- behavior, which is not the default,
+ to change this behavior to match <application>PL/SQL</application>,
as explained in <xref linkend="plpgsql-var-subst"/>.
It's often best to avoid such ambiguities in the first place,
but if you have to port a large amount of code that depends on