Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit cfd2728

Browse files
committed
This patch makes a minor cleanup to the implementation of PERFORM in
PL/PgSQL. Previously, it had been bundled together with the assign statement implementation, for some reason that wasn't clear to me (they certainly don't share any code with one another). So I separated them and made PERFORM a statement like any other. No changes in functionality. Along the way, I added some regression tests for PERFORM, added a bunch more SGML tags to the PL/PgSQL docs, and removed an obsolete comment relating to the implementation of RETURN NEXT. Neil Conway
1 parent ceb4f5e commit cfd2728

File tree

6 files changed

+258
-144
lines changed

6 files changed

+258
-144
lines changed

doc/src/sgml/plpgsql.sgml

Lines changed: 109 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/plpgsql.sgml,v 1.8 2002/09/21 18:32:53 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/plpgsql.sgml,v 1.9 2002/11/10 00:35:58 momjian Exp $
33
-->
44

55
<chapter id="plpgsql">
@@ -102,7 +102,7 @@ END;
102102
</programlisting>
103103
If you execute the above function, it will reference the OID for
104104
<function>my_function()</function> in the query plan produced for
105-
the PERFORM statement. Later, if you
105+
the <command>PERFORM</command> statement. Later, if you
106106
drop and re-create <function>my_function()</function>, then
107107
<function>populate()</function> will not be able to find
108108
<function>my_function()</function> anymore. You would then have to
@@ -117,17 +117,19 @@ END;
117117
same tables and fields on every execution; that is, you cannot use
118118
a parameter as the name of a table or field in a query. To get
119119
around this restriction, you can construct dynamic queries using
120-
the <application>PL/pgSQL</application> EXECUTE statement --- at
121-
the price of constructing a new query plan on every execution.
120+
the <application>PL/pgSQL</application> <command>EXECUTE</command>
121+
statement --- at the price of constructing a new query plan on
122+
every execution.
122123
</para>
123124

124125
<note>
125126
<para>
126-
The <application>PL/pgSQL</application> EXECUTE statement is not
127-
related to the EXECUTE statement supported by the
127+
The <application>PL/pgSQL</application>
128+
<command>EXECUTE</command> statement is not related to the
129+
<command>EXECUTE</command> statement supported by the
128130
<productname>PostgreSQL</productname> backend. The backend
129-
EXECUTE statement cannot be used within <application>PL/pgSQL</> functions (and
130-
is not needed).
131+
<command>EXECUTE</command> statement cannot be used within
132+
<application>PL/pgSQL</> functions (and is not needed).
131133
</para>
132134
</note>
133135

@@ -173,13 +175,12 @@ END;
173175
</para>
174176

175177
<para>
176-
That means that your client application must send each
177-
query to the database server, wait for it to process it,
178-
receive the results, do some computation, then send
179-
other queries to the server. All this incurs inter-process communication
180-
and may also incur network
181-
overhead if your client is on a different machine than
182-
the database server.
178+
That means that your client application must send each query to
179+
the database server, wait for it to process it, receive the
180+
results, do some computation, then send other queries to the
181+
server. All this incurs inter-process communication and may also
182+
incur network overhead if your client is on a different machine
183+
than the database server.
183184
</para>
184185

185186
<para>
@@ -753,14 +754,14 @@ CREATE FUNCTION logfunc2 (TEXT) RETURNS TIMESTAMP AS '
753754

754755
<para>
755756
The mutable nature of record variables presents a problem in this
756-
connection. When fields of a record variable are used in expressions or
757-
statements, the data types of the
758-
fields must not change between calls of one and the same expression,
759-
since the expression will be planned using the data type that is present
760-
when the expression is first reached.
761-
Keep this in mind when writing trigger procedures that handle events
762-
for more than one table. (EXECUTE can be used to get around this
763-
problem when necessary.)
757+
connection. When fields of a record variable are used in
758+
expressions or statements, the data types of the fields must not
759+
change between calls of one and the same expression, since the
760+
expression will be planned using the data type that is present
761+
when the expression is first reached. Keep this in mind when
762+
writing trigger procedures that handle events for more than one
763+
table. (<command>EXECUTE</command> can be used to get around
764+
this problem when necessary.)
764765
</para>
765766
</sect1>
766767

@@ -904,10 +905,11 @@ END;
904905
<title>Executing an expression or query with no result</title>
905906

906907
<para>
907-
Sometimes one wishes to evaluate an expression or query but discard
908-
the result (typically because one is calling a function that has
909-
useful side-effects but no useful result value). To do this in
910-
<application>PL/pgSQL</application>, use the PERFORM statement:
908+
Sometimes one wishes to evaluate an expression or query but
909+
discard the result (typically because one is calling a function
910+
that has useful side-effects but no useful result value). To do
911+
this in <application>PL/pgSQL</application>, use the
912+
<command>PERFORM</command> statement:
911913

912914
<synopsis>
913915
PERFORM <replaceable>query</replaceable>;
@@ -922,11 +924,12 @@ PERFORM <replaceable>query</replaceable>;
922924
</para>
923925

924926
<note>
925-
<para>
926-
One might expect that SELECT with no INTO clause would accomplish
927-
this result, but at present the only accepted way to do it is PERFORM.
928-
</para>
929-
</note>
927+
<para>
928+
One might expect that <command>SELECT</command> with no INTO
929+
clause would accomplish this result, but at present the only
930+
accepted way to do it is <command>PERFORM</command>.
931+
</para>
932+
</note>
930933

931934
<para>
932935
An example:
@@ -940,13 +943,13 @@ PERFORM create_mv(''cs_session_page_requests_mv'', my_query);
940943
<title>Executing dynamic queries</title>
941944

942945
<para>
943-
Oftentimes you will want to generate dynamic queries inside
944-
your <application>PL/pgSQL</application> functions, that is,
945-
queries that will involve different tables or different data types
946-
each time they are executed. <application>PL/pgSQL</application>'s
946+
Oftentimes you will want to generate dynamic queries inside your
947+
<application>PL/pgSQL</application> functions, that is, queries
948+
that will involve different tables or different data types each
949+
time they are executed. <application>PL/pgSQL</application>'s
947950
normal attempts to cache plans for queries will not work in such
948-
scenarios. To handle this sort of problem, the EXECUTE statement
949-
is provided:
951+
scenarios. To handle this sort of problem, the
952+
<command>EXECUTE</command> statement is provided:
950953

951954
<synopsis>
952955
EXECUTE <replaceable class="command">query-string</replaceable>;
@@ -973,20 +976,22 @@ EXECUTE <replaceable class="command">query-string</replaceable>;
973976

974977
<para>
975978
Unlike all other queries in <application>PL/pgSQL</>, a
976-
<replaceable>query</replaceable> run by an EXECUTE statement is
977-
not prepared and saved just once during the life of the server.
978-
Instead, the <replaceable>query</replaceable> is prepared each
979-
time the statement is run. The
980-
<replaceable>query-string</replaceable> can be dynamically
981-
created within the procedure to perform actions on variable
982-
tables and fields.
979+
<replaceable>query</replaceable> run by an
980+
<command>EXECUTE</command> statement is not prepared and saved
981+
just once during the life of the server. Instead, the
982+
<replaceable>query</replaceable> is prepared each time the
983+
statement is run. The <replaceable>query-string</replaceable> can
984+
be dynamically created within the procedure to perform actions on
985+
variable tables and fields.
983986
</para>
984987

985988
<para>
986-
The results from SELECT queries are discarded by EXECUTE, and
987-
SELECT INTO is not currently supported within EXECUTE. So, the
988-
only way to extract a result from a dynamically-created SELECT is
989-
to use the FOR-IN-EXECUTE form described later.
989+
The results from <command>SELECT</command> queries are discarded
990+
by <command>EXECUTE</command>, and <command>SELECT INTO</command>
991+
is not currently supported within <command>EXECUTE</command>.
992+
So, the only way to extract a result from a dynamically-created
993+
<command>SELECT</command> is to use the FOR-IN-EXECUTE form
994+
described later.
990995
</para>
991996

992997
<para>
@@ -1017,7 +1022,8 @@ EXECUTE ''UPDATE tbl SET ''
10171022
</para>
10181023

10191024
<para>
1020-
Here is a much larger example of a dynamic query and EXECUTE:
1025+
Here is a much larger example of a dynamic query and
1026+
<command>EXECUTE</command>:
10211027
<programlisting>
10221028
CREATE FUNCTION cs_update_referrer_type_proc() RETURNS INTEGER AS '
10231029
DECLARE
@@ -1159,9 +1165,9 @@ GET DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replace
11591165
RETURN <replaceable>expression</replaceable>;
11601166
</synopsis>
11611167

1162-
RETURN with an expression is used to return from a
1163-
<application>PL/pgSQL</> function that does not return a set.
1164-
The function terminates and the value of
1168+
<command>RETURN</command> with an expression is used to return
1169+
from a <application>PL/pgSQL</> function that does not return a
1170+
set. The function terminates and the value of
11651171
<replaceable>expression</replaceable> is returned to the caller.
11661172
</para>
11671173

@@ -1176,22 +1182,24 @@ RETURN <replaceable>expression</replaceable>;
11761182
</para>
11771183

11781184
<para>
1179-
The return value of a function cannot be left undefined. If control
1180-
reaches the end of the top-level block of
1181-
the function without hitting a RETURN statement, a run-time error
1182-
will occur.
1185+
The return value of a function cannot be left undefined. If
1186+
control reaches the end of the top-level block of the function
1187+
without hitting a <command>RETURN</command> statement, a run-time
1188+
error will occur.
11831189
</para>
11841190

11851191
<para>
11861192
When a <application>PL/pgSQL</> function is declared to return
11871193
<literal>SETOF</literal> <replaceable>sometype</>, the procedure
11881194
to follow is slightly different. In that case, the individual
1189-
items to return are specified in RETURN NEXT commands, and then a
1190-
final RETURN command with no arguments is used to indicate that
1191-
the function has finished executing. RETURN NEXT can be used with
1192-
both scalar and composite data types; in the later case, an
1193-
entire "table" of results will be returned. Functions that use
1194-
RETURN NEXT should be called in the following fashion:
1195+
items to return are specified in <command>RETURN NEXT</command>
1196+
commands, and then a final <command>RETURN</command> command with
1197+
no arguments is used to indicate that the function has finished
1198+
executing. <command>RETURN NEXT</command> can be used with both
1199+
scalar and composite data types; in the later case, an entire
1200+
"table" of results will be returned. Functions that use
1201+
<command>RETURN NEXT</command> should be called in the following
1202+
fashion:
11951203

11961204
<programlisting>
11971205
SELECT * FROM some_func();
@@ -1203,19 +1211,19 @@ SELECT * FROM some_func();
12031211
RETURN NEXT <replaceable>expression</replaceable>;
12041212
</synopsis>
12051213

1206-
RETURN NEXT does not actually return from the function; it simply
1207-
saves away the value of the expression (or record or row variable,
1208-
as appropriate for the data type being returned).
1209-
Execution then continues with the next statement in the
1210-
<application>PL/pgSQL</> function. As successive RETURN NEXT
1211-
commands are executed, the result set is built up. A final
1212-
RETURN, which need have no argument, causes control to exit
1213-
the function.
1214+
<command>RETURN NEXT</command> does not actually return from the
1215+
function; it simply saves away the value of the expression (or
1216+
record or row variable, as appropriate for the data type being
1217+
returned). Execution then continues with the next statement in
1218+
the <application>PL/pgSQL</> function. As successive
1219+
<command>RETURN NEXT</command> commands are executed, the result
1220+
set is built up. A final <command>RETURN</commmand>, which need
1221+
have no argument, causes control to exit the function.
12141222
</para>
12151223

12161224
<note>
12171225
<para>
1218-
The current implementation of RETURN NEXT for
1226+
The current implementation of <command>RETURN NEXT</command> for
12191227
<application>PL/pgSQL</> stores the entire result set before
12201228
returning from the function, as discussed above. That means that
12211229
if a <application>PL/pgSQL</> function produces a very large result set,
@@ -1586,12 +1594,12 @@ FOR <replaceable>record | row</replaceable> IN EXECUTE <replaceable>text_express
15861594
<replaceable>statements</replaceable>
15871595
END LOOP;
15881596
</synopsis>
1589-
This is like the previous form, except that the source SELECT
1590-
statement is specified as a string expression, which is evaluated
1591-
and re-planned on each entry to the FOR loop. This allows the
1592-
programmer to choose the speed of a pre-planned query or the
1593-
flexibility of a dynamic query, just as with a plain EXECUTE
1594-
statement.
1597+
This is like the previous form, except that the source
1598+
<command>SELECT</command> statement is specified as a string
1599+
expression, which is evaluated and re-planned on each entry to
1600+
the FOR loop. This allows the programmer to choose the speed of
1601+
a pre-planned query or the flexibility of a dynamic query, just
1602+
as with a plain <command>EXECUTE</command> statement.
15951603
</para>
15961604

15971605
<note>
@@ -1700,18 +1708,18 @@ OPEN curs1 FOR SELECT * FROM foo WHERE key = mykey;
17001708
<sect3>
17011709
<title>OPEN FOR EXECUTE</title>
17021710

1703-
<para>
1711+
<para>
17041712
<synopsis>
17051713
OPEN <replaceable>unbound-cursor</replaceable> FOR EXECUTE <replaceable class="command">query-string</replaceable>;
17061714
</synopsis>
17071715

1708-
The cursor variable is opened and given the specified query
1709-
to execute. The cursor cannot be open already, and it must
1710-
have been declared as an unbound cursor (that is, as a simple
1711-
<type>refcursor</> variable). The query is specified as a
1712-
string expression in the same way as in the EXECUTE command.
1713-
As usual, this gives flexibility so the query can vary
1714-
from one run to the next.
1716+
The cursor variable is opened and given the specified query to
1717+
execute. The cursor cannot be open already, and it must have been
1718+
declared as an unbound cursor (that is, as a simple
1719+
<type>refcursor</> variable). The query is specified as a string
1720+
expression in the same way as in the <command>EXECUTE</command>
1721+
command. As usual, this gives flexibility so the query can vary
1722+
from one run to the next.
17151723

17161724
<programlisting>
17171725
OPEN curs1 FOR EXECUTE ''SELECT * FROM '' || quote_ident($1);
@@ -1722,19 +1730,18 @@ OPEN curs1 FOR EXECUTE ''SELECT * FROM '' || quote_ident($1);
17221730
<sect3>
17231731
<title>Opening a bound cursor</title>
17241732

1725-
<para>
1733+
<para>
17261734
<synopsis>
17271735
OPEN <replaceable>bound-cursor</replaceable> <optional> ( <replaceable>argument_values</replaceable> ) </optional>;
17281736
</synopsis>
17291737

1730-
This form of OPEN is used to open a cursor variable whose query
1731-
was bound to it when it was declared.
1732-
The cursor cannot be open already. A list of actual argument
1733-
value expressions must appear if and only if the cursor was
1734-
declared to take arguments. These values will be substituted
1735-
in the query.
1736-
The query plan for a bound cursor is always considered
1737-
cacheable --- there is no equivalent of EXECUTE in this case.
1738+
This form of <command>OPEN</command> is used to open a cursor
1739+
variable whose query was bound to it when it was declared. The
1740+
cursor cannot be open already. A list of actual argument value
1741+
expressions must appear if and only if the cursor was declared to
1742+
take arguments. These values will be substituted in the query.
1743+
The query plan for a bound cursor is always considered cacheable
1744+
--- there is no equivalent of <command>EXECUTE</command> in this case.
17381745

17391746
<programlisting>
17401747
OPEN curs2;
@@ -1771,16 +1778,17 @@ OPEN curs3(42);
17711778
<sect3>
17721779
<title>FETCH</title>
17731780

1774-
<para>
1781+
<para>
17751782
<synopsis>
17761783
FETCH <replaceable>cursor</replaceable> INTO <replaceable>target</replaceable>;
17771784
</synopsis>
17781785

1779-
FETCH retrieves the next row from the cursor into a target,
1780-
which may be a row variable, a record variable, or a comma-separated
1781-
list of simple variables, just like SELECT INTO. As with
1782-
SELECT INTO, the special variable <literal>FOUND</literal> may be
1783-
checked to see whether a row was obtained or not.
1786+
<command>FETCH</command> retrieves the next row from the
1787+
cursor into a target, which may be a row variable, a record
1788+
variable, or a comma-separated list of simple variables, just like
1789+
<command>SELECT INTO</command>. As with <command>SELECT
1790+
INTO</command>, the special variable <literal>FOUND</literal> may
1791+
be checked to see whether a row was obtained or not.
17841792

17851793
<programlisting>
17861794
FETCH curs1 INTO rowvar;

src/pl/plpgsql/src/gram.y

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* procedural language
55
*
66
* IDENTIFICATION
7-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.39 2002/11/01 22:52:34 tgl Exp $
7+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.40 2002/11/10 00:35:58 momjian Exp $
88
*
99
* This software is copyrighted by Jan Wieck - Hamburg.
1010
*
@@ -728,14 +728,13 @@ proc_stmt : pl_block ';'
728728

729729
stmt_perform : K_PERFORM lno expr_until_semi
730730
{
731-
PLpgSQL_stmt_assign *new;
731+
PLpgSQL_stmt_perform *new;
732732

733-
new = malloc(sizeof(PLpgSQL_stmt_assign));
734-
memset(new, 0, sizeof(PLpgSQL_stmt_assign));
733+
new = malloc(sizeof(PLpgSQL_stmt_perform));
734+
memset(new, 0, sizeof(PLpgSQL_stmt_perform));
735735

736-
new->cmd_type = PLPGSQL_STMT_ASSIGN;
736+
new->cmd_type = PLPGSQL_STMT_PERFORM;
737737
new->lineno = $2;
738-
new->varno = -1;
739738
new->expr = $3;
740739

741740
$$ = (PLpgSQL_stmt *)new;

0 commit comments

Comments
 (0)