Skip to content

Commit c783e65

Browse files
committed
Doc: improve discussion of variable substitution in PL/pgSQL.
This was a bit disjointed, partly because of a not-well-considered decision to document SQL commands that don't return result rows as though they had nothing in common with commands that do. Rearrange so that we have one discussion of variable substitution that clearly applies to all types of SQL commands, and then handle the question of processing command output separately. Clarify that EXPLAIN, CREATE TABLE AS SELECT, and similar commands that incorporate an optimizable statement will act like optimizable statements for the purposes of variable substitution. Do a bunch of minor wordsmithing in the same area. David Johnston and Tom Lane, reviewed by Pavel Stehule and David Steele Discussion: https://postgr.es/m/CAKFQuwYvMKucM5fnZvHSo-ah4S=_n9gmKeu6EAo=_fTrohunqQ@mail.gmail.com
1 parent 7f7f25f commit c783e65

File tree

1 file changed

+114
-58
lines changed

1 file changed

+114
-58
lines changed

doc/src/sgml/plpgsql.sgml

+114-58
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ SELECT <replaceable>expression</replaceable>
894894
</synopsis>
895895
to the main SQL engine. While forming the <command>SELECT</command> command,
896896
any occurrences of <application>PL/pgSQL</application> variable names
897-
are replaced by parameters, as discussed in detail in
897+
are replaced by query parameters, as discussed in detail in
898898
<xref linkend="plpgsql-var-subst"/>.
899899
This allows the query plan for the <command>SELECT</command> to
900900
be prepared just once and then reused for subsequent
@@ -946,8 +946,7 @@ IF count(*) &gt; 0 FROM my_table THEN ...
946946
<application>PL/pgSQL</application>.
947947
Anything not recognized as one of these statement types is presumed
948948
to be an SQL command and is sent to the main database engine to execute,
949-
as described in <xref linkend="plpgsql-statements-sql-noresult"/>
950-
and <xref linkend="plpgsql-statements-sql-onerow"/>.
949+
as described in <xref linkend="plpgsql-statements-general-sql"/>.
951950
</para>
952951

953952
<sect2 id="plpgsql-statements-assignment">
@@ -993,31 +992,78 @@ complex_array[n].realpart = 12.3;
993992
</para>
994993
</sect2>
995994

996-
<sect2 id="plpgsql-statements-sql-noresult">
997-
<title>Executing a Command with No Result</title>
995+
<sect2 id="plpgsql-statements-general-sql">
996+
<title>Executing SQL Commands</title>
998997

999998
<para>
1000-
For any SQL command that does not return rows, for example
1001-
<command>INSERT</command> without a <literal>RETURNING</literal> clause, you can
1002-
execute the command within a <application>PL/pgSQL</application> function
1003-
just by writing the command.
999+
In general, any SQL command that does not return rows can be executed
1000+
within a <application>PL/pgSQL</application> function just by writing
1001+
the command. For example, you could create and fill a table by writing
1002+
<programlisting>
1003+
CREATE TABLE mytable (id int primary key, data text);
1004+
INSERT INTO mytable VALUES (1,'one'), (2,'two');
1005+
</programlisting>
10041006
</para>
10051007

10061008
<para>
1007-
Any <application>PL/pgSQL</application> variable name appearing
1008-
in the command text is treated as a parameter, and then the
1009+
If the command does return rows (for example <command>SELECT</command>,
1010+
or <command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>
1011+
with <literal>RETURNING</literal>), there are two ways to proceed.
1012+
When the command will return at most one row, or you only care about
1013+
the first row of output, write the command as usual but add
1014+
an <literal>INTO</literal> clause to capture the output, as described
1015+
in <xref linkend="plpgsql-statements-sql-onerow"/>.
1016+
To process all of the output rows, write the command as the data
1017+
source for a <command>FOR</command> loop, as described in
1018+
<xref linkend="plpgsql-records-iterating"/>.
1019+
</para>
1020+
1021+
<para>
1022+
Usually it is not sufficient just to execute statically-defined SQL
1023+
commands. Typically you'll want a command to use varying data values,
1024+
or even to vary in more fundamental ways such as by using different
1025+
table names at different times. Again, there are two ways to proceed
1026+
depending on the situation.
1027+
</para>
1028+
1029+
<para>
1030+
<application>PL/pgSQL</application> variable values can be
1031+
automatically inserted into optimizable SQL commands, which
1032+
are <command>SELECT</command>, <command>INSERT</command>,
1033+
<command>UPDATE</command>, <command>DELETE</command>, and certain
1034+
utility commands that incorporate one of these, such
1035+
as <command>EXPLAIN</command> and <command>CREATE TABLE ... AS
1036+
SELECT</command>. In these commands,
1037+
any <application>PL/pgSQL</application> variable name appearing
1038+
in the command text is replaced by a query parameter, and then the
10091039
current value of the variable is provided as the parameter value
10101040
at run time. This is exactly like the processing described earlier
10111041
for expressions; for details see <xref linkend="plpgsql-var-subst"/>.
10121042
</para>
10131043

10141044
<para>
1015-
When executing a SQL command in this way,
1045+
When executing an optimizable SQL command in this way,
10161046
<application>PL/pgSQL</application> may cache and re-use the execution
10171047
plan for the command, as discussed in
10181048
<xref linkend="plpgsql-plan-caching"/>.
10191049
</para>
10201050

1051+
<para>
1052+
Non-optimizable SQL commands (also called utility commands) are not
1053+
capable of accepting query parameters. So automatic substitution
1054+
of <application>PL/pgSQL</application> variables does not work in such
1055+
commands. To include non-constant text in a utility command executed
1056+
from <application>PL/pgSQL</application>, you must build the utility
1057+
command as a string and then <command>EXECUTE</command> it, as
1058+
discussed in <xref linkend="plpgsql-statements-executing-dyn"/>.
1059+
</para>
1060+
1061+
<para>
1062+
<command>EXECUTE</command> must also be used if you want to modify
1063+
the command in some other way than supplying a data value, for example
1064+
by changing a table name.
1065+
</para>
1066+
10211067
<para>
10221068
Sometimes it is useful to evaluate an expression or <command>SELECT</command>
10231069
query but discard the result, for example when calling a function
@@ -1037,7 +1083,7 @@ PERFORM <replaceable>query</replaceable>;
10371083
place the query in parentheses. (In this case, the query can only
10381084
return one row.)
10391085
<application>PL/pgSQL</application> variables will be
1040-
substituted into the query just as for commands that return no result,
1086+
substituted into the query just as described above,
10411087
and the plan is cached in the same way. Also, the special variable
10421088
<literal>FOUND</literal> is set to true if the query produced at
10431089
least one row, or false if it produced no rows (see
@@ -1065,7 +1111,7 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query);
10651111
</sect2>
10661112

10671113
<sect2 id="plpgsql-statements-sql-onerow">
1068-
<title>Executing a Query with a Single-Row Result</title>
1114+
<title>Executing a Command with a Single-Row Result</title>
10691115

10701116
<indexterm zone="plpgsql-statements-sql-onerow">
10711117
<primary>SELECT INTO</primary>
@@ -1094,12 +1140,13 @@ DELETE ... RETURNING <replaceable>expressions</replaceable> INTO <optional>STRIC
10941140
variable, or a comma-separated list of simple variables and
10951141
record/row fields.
10961142
<application>PL/pgSQL</application> variables will be
1097-
substituted into the rest of the query, and the plan is cached,
1098-
just as described above for commands that do not return rows.
1143+
substituted into the rest of the command (that is, everything but the
1144+
<literal>INTO</literal> clause) just as described above,
1145+
and the plan is cached in the same way.
10991146
This works for <command>SELECT</command>,
11001147
<command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command> with
1101-
<literal>RETURNING</literal>, and utility commands that return row-set
1102-
results (such as <command>EXPLAIN</command>).
1148+
<literal>RETURNING</literal>, and certain utility commands
1149+
that return row sets, such as <command>EXPLAIN</command>.
11031150
Except for the <literal>INTO</literal> clause, the SQL command is the same
11041151
as it would be written outside <application>PL/pgSQL</application>.
11051152
</para>
@@ -1117,11 +1164,12 @@ DELETE ... RETURNING <replaceable>expressions</replaceable> INTO <optional>STRIC
11171164
</tip>
11181165

11191166
<para>
1120-
If a row or a variable list is used as target, the query's result columns
1167+
If a row variable or a variable list is used as target,
1168+
the command's result columns
11211169
must exactly match the structure of the target as to number and data
11221170
types, or else a run-time error
11231171
occurs. When a record variable is the target, it automatically
1124-
configures itself to the row type of the query result columns.
1172+
configures itself to the row type of the command's result columns.
11251173
</para>
11261174

11271175
<para>
@@ -1137,7 +1185,7 @@ DELETE ... RETURNING <replaceable>expressions</replaceable> INTO <optional>STRIC
11371185
<para>
11381186
If <literal>STRICT</literal> is not specified in the <literal>INTO</literal>
11391187
clause, then <replaceable>target</replaceable> will be set to the first
1140-
row returned by the query, or to nulls if the query returned no rows.
1188+
row returned by the command, or to nulls if the command returned no rows.
11411189
(Note that <quote>the first row</quote> is not
11421190
well-defined unless you've used <literal>ORDER BY</literal>.) Any result rows
11431191
after the first row are discarded.
@@ -1152,7 +1200,7 @@ IF NOT FOUND THEN
11521200
END IF;
11531201
</programlisting>
11541202

1155-
If the <literal>STRICT</literal> option is specified, the query must
1203+
If the <literal>STRICT</literal> option is specified, the command must
11561204
return exactly one row or a run-time error will be reported, either
11571205
<literal>NO_DATA_FOUND</literal> (no rows) or <literal>TOO_MANY_ROWS</literal>
11581206
(more than one row). You can use an exception block if you wish
@@ -1186,7 +1234,7 @@ END;
11861234
then when an error is thrown because the requirements
11871235
of <literal>STRICT</literal> are not met, the <literal>DETAIL</literal> part of
11881236
the error message will include information about the parameters
1189-
passed to the query.
1237+
passed to the command.
11901238
You can change the <literal>print_strict_params</literal>
11911239
setting for all functions by setting
11921240
<varname>plpgsql.print_strict_params</varname>, though only subsequent
@@ -1220,11 +1268,6 @@ CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement
12201268
</para>
12211269
</note>
12221270

1223-
<para>
1224-
To handle cases where you need to process multiple result rows
1225-
from a SQL query, see <xref linkend="plpgsql-records-iterating"/>.
1226-
</para>
1227-
12281271
</sect2>
12291272

12301273
<sect2 id="plpgsql-statements-executing-dyn">
@@ -1270,20 +1313,20 @@ EXECUTE <replaceable class="command">command-string</replaceable> <optional> INT
12701313

12711314
<para>
12721315
The <literal>INTO</literal> clause specifies where the results of
1273-
a SQL command returning rows should be assigned. If a row
1316+
a SQL command returning rows should be assigned. If a row variable
12741317
or variable list is provided, it must exactly match the structure
1275-
of the query's results (when a
1276-
record variable is used, it will configure itself to match the
1277-
result structure automatically). If multiple rows are returned,
1318+
of the command's results; if a
1319+
record variable is provided, it will configure itself to match the
1320+
result structure automatically. If multiple rows are returned,
12781321
only the first will be assigned to the <literal>INTO</literal>
1279-
variable. If no rows are returned, NULL is assigned to the
1322+
variable(s). If no rows are returned, NULL is assigned to the
12801323
<literal>INTO</literal> variable(s). If no <literal>INTO</literal>
1281-
clause is specified, the query results are discarded.
1324+
clause is specified, the command results are discarded.
12821325
</para>
12831326

12841327
<para>
12851328
If the <literal>STRICT</literal> option is given, an error is reported
1286-
unless the query produces exactly one row.
1329+
unless the command produces exactly one row.
12871330
</para>
12881331

12891332
<para>
@@ -1316,17 +1359,23 @@ EXECUTE 'SELECT count(*) FROM '
13161359
USING checked_user, checked_date;
13171360
</programlisting>
13181361
A cleaner approach is to use <function>format()</function>'s <literal>%I</literal>
1319-
specification for table or column names (strings separated by a
1320-
newline are concatenated):
1362+
specification to insert table or column names with automatic quoting:
13211363
<programlisting>
13221364
EXECUTE format('SELECT count(*) FROM %I '
13231365
'WHERE inserted_by = $1 AND inserted &lt;= $2', tabname)
13241366
INTO c
13251367
USING checked_user, checked_date;
13261368
</programlisting>
1369+
(This example relies on the SQL rule that string literals separated by a
1370+
newline are implicitly concatenated.)
1371+
</para>
1372+
1373+
<para>
13271374
Another restriction on parameter symbols is that they only work in
1328-
<command>SELECT</command>, <command>INSERT</command>, <command>UPDATE</command>, and
1329-
<command>DELETE</command> commands. In other statement
1375+
optimizable SQL commands
1376+
(<command>SELECT</command>, <command>INSERT</command>, <command>UPDATE</command>,
1377+
<command>DELETE</command>, and certain commands containing one of these).
1378+
In other statement
13301379
types (generically called utility statements), you must insert
13311380
values textually even if they are just data values.
13321381
</para>
@@ -2567,7 +2616,7 @@ $$ LANGUAGE plpgsql;
25672616
</para>
25682617

25692618
<para>
2570-
<application>PL/pgSQL</application> variables are substituted into the query text,
2619+
<application>PL/pgSQL</application> variables are replaced by query parameters,
25712620
and the query plan is cached for possible re-use, as discussed in
25722621
detail in <xref linkend="plpgsql-var-subst"/> and
25732622
<xref linkend="plpgsql-plan-caching"/>.
@@ -4643,26 +4692,29 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch();
46434692
SQL statements and expressions within a <application>PL/pgSQL</application> function
46444693
can refer to variables and parameters of the function. Behind the scenes,
46454694
<application>PL/pgSQL</application> substitutes query parameters for such references.
4646-
Parameters will only be substituted in places where a parameter or
4647-
column reference is syntactically allowed. As an extreme case, consider
4695+
Query parameters will only be substituted in places where they are
4696+
syntactically permissible. As an extreme case, consider
46484697
this example of poor programming style:
46494698
<programlisting>
4650-
INSERT INTO foo (foo) VALUES (foo);
4699+
INSERT INTO foo (foo) VALUES (foo(foo));
46514700
</programlisting>
46524701
The first occurrence of <literal>foo</literal> must syntactically be a table
46534702
name, so it will not be substituted, even if the function has a variable
46544703
named <literal>foo</literal>. The second occurrence must be the name of a
4655-
column of the table, so it will not be substituted either. Only the
4656-
third occurrence is a candidate to be a reference to the function's
4657-
variable.
4704+
column of that table, so it will not be substituted either. Likewise
4705+
the third occurrence must be a function name, so it also will not be
4706+
substituted for. Only the last occurrence is a candidate to be a
4707+
reference to a variable of the <application>PL/pgSQL</application>
4708+
function.
46584709
</para>
46594710

4660-
<note>
4661-
<para>
4662-
<productname>PostgreSQL</productname> versions before 9.0 would try
4663-
to substitute the variable in all three cases, leading to syntax errors.
4664-
</para>
4665-
</note>
4711+
<para>
4712+
Another way to understand this is that variable substitution can only
4713+
insert data values into a SQL command; it cannot dynamically change which
4714+
database objects are referenced by the command. (If you want to do
4715+
that, you must build a command string dynamically, as explained in
4716+
<xref linkend="plpgsql-statements-executing-dyn"/>.)
4717+
</para>
46664718

46674719
<para>
46684720
Since the names of variables are syntactically no different from the names
@@ -4790,7 +4842,7 @@ $$ LANGUAGE plpgsql;
47904842
</para>
47914843

47924844
<para>
4793-
Variable substitution does not happen in the command string given
4845+
Variable substitution does not happen in a command string given
47944846
to <command>EXECUTE</command> or one of its variants. If you need to
47954847
insert a varying value into such a command, do so as part of
47964848
constructing the string value, or use <literal>USING</literal>, as illustrated in
@@ -4799,7 +4851,10 @@ $$ LANGUAGE plpgsql;
47994851

48004852
<para>
48014853
Variable substitution currently works only in <command>SELECT</command>,
4802-
<command>INSERT</command>, <command>UPDATE</command>, and <command>DELETE</command> commands,
4854+
<command>INSERT</command>, <command>UPDATE</command>,
4855+
<command>DELETE</command>, and commands containing one of
4856+
these (such as <command>EXPLAIN</command> and <command>CREATE TABLE
4857+
... AS SELECT</command>),
48034858
because the main SQL engine allows query parameters only in these
48044859
commands. To use a non-constant name or value in other statement
48054860
types (generically called utility statements), you must construct
@@ -5314,11 +5369,12 @@ HINT: Make sure the query returns the exact list of columns.
53145369
<listitem>
53155370
<para>
53165371
If a name used in a SQL command could be either a column name of a
5317-
table or a reference to a variable of the function,
5318-
<application>PL/SQL</application> treats it as a column name. This corresponds
5319-
to <application>PL/pgSQL</application>'s
5372+
table used in the command or a reference to a variable of the function,
5373+
<application>PL/SQL</application> treats it as a column name.
5374+
By default, <application>PL/pgSQL</application> will throw an error
5375+
complaining that the name is ambiguous. You can specify
53205376
<literal>plpgsql.variable_conflict</literal> = <literal>use_column</literal>
5321-
behavior, which is not the default,
5377+
to change this behavior to match <application>PL/SQL</application>,
53225378
as explained in <xref linkend="plpgsql-var-subst"/>.
53235379
It's often best to avoid such ambiguities in the first place,
53245380
but if you have to port a large amount of code that depends on

0 commit comments

Comments
 (0)