1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-24 10:47:04 +03:00

Doc: improve description of plpgsql's FETCH and MOVE commands.

We were not being clear about which variants of the "direction"
clause are permitted in MOVE.  Also, the text seemed to be
written with only the FETCH/MOVE NEXT case in mind, so it
didn't apply very well to other variants.

Also, document that "MOVE count IN cursor" only works if count
is a constant.  This is not the whole truth, because some other
cases such as a parenthesized expression will also work, but
we want to push people to use "MOVE FORWARD count" instead.
The constant case is enough to cover what we allow in plain SQL,
and that seems sufficient to claim support for.

Update a comment in pl_gram.y claiming that we don't document
that point.

Per gripe from Philipp Salvisberg.

Discussion: https://postgr.es/m/172155553388.702.7932496598218792085@wrigleys.postgresql.org
This commit is contained in:
Tom Lane 2024-07-22 19:43:12 -04:00
parent efcbb76efe
commit d2cba4f2cb
2 changed files with 28 additions and 11 deletions

View File

@ -3409,13 +3409,16 @@ FETCH <optional> <replaceable>direction</replaceable> { FROM | IN } </optional>
</synopsis> </synopsis>
<para> <para>
<command>FETCH</command> retrieves the next row from the <command>FETCH</command> retrieves the next row (in the indicated
direction) from the
cursor into a target, which might be a row variable, a record cursor into a target, which might be a row variable, a record
variable, or a comma-separated list of simple variables, just like variable, or a comma-separated list of simple variables, just like
<command>SELECT INTO</command>. If there is no next row, the <command>SELECT INTO</command>. If there is no suitable row, the
target is set to NULL(s). As with <command>SELECT target is set to NULL(s). As with <command>SELECT
INTO</command>, the special variable <literal>FOUND</literal> can INTO</command>, the special variable <literal>FOUND</literal> can
be checked to see whether a row was obtained or not. be checked to see whether a row was obtained or not. If no row is
obtained, the cursor is positioned after the last row or before the
first row, depending on the movement direction.
</para> </para>
<para> <para>
@ -3467,11 +3470,25 @@ MOVE <optional> <replaceable>direction</replaceable> { FROM | IN } </optional> <
<para> <para>
<command>MOVE</command> repositions a cursor without retrieving <command>MOVE</command> repositions a cursor without retrieving
any data. <command>MOVE</command> works exactly like the any data. <command>MOVE</command> works like the
<command>FETCH</command> command, except it only repositions the <command>FETCH</command> command, except it only repositions the
cursor and does not return the row moved to. As with <command>SELECT cursor and does not return the row moved to.
The <replaceable>direction</replaceable> clause can be any of the
variants allowed in the SQL <xref linkend="sql-fetch"/>
command, including those that can fetch more than one row;
the cursor is positioned to the last such row.
(However, the case in which the <replaceable>direction</replaceable>
clause is simply a <replaceable>count</replaceable> expression with
no key word is deprecated in <application>PL/pgSQL</application>.
That syntax is ambiguous with the case where
the <replaceable>direction</replaceable> clause is omitted
altogether, and hence it may fail if
the <replaceable>count</replaceable> is not a constant.)
As with <command>SELECT
INTO</command>, the special variable <literal>FOUND</literal> can INTO</command>, the special variable <literal>FOUND</literal> can
be checked to see whether there was a next row to move to. be checked to see whether there was a row to move to. If there is no
such row, the cursor is positioned after the last row or before the
first row, depending on the movement direction.
</para> </para>
<para> <para>

View File

@ -3219,11 +3219,11 @@ read_fetch_direction(void)
{ {
/* /*
* Assume it's a count expression with no preceding keyword. * Assume it's a count expression with no preceding keyword.
* Note: we allow this syntax because core SQL does, but we don't * Note: we allow this syntax because core SQL does, but it's
* document it because of the ambiguity with the omitted-direction * ambiguous with the case of an omitted direction clause; for
* case. For instance, "MOVE n IN c" will fail if n is a variable. * instance, "MOVE n IN c" will fail if n is a variable, because the
* Perhaps this can be improved someday, but it's hardly worth a * preceding else-arm will trigger. Perhaps this can be improved
* lot of work. * someday, but it hardly seems worth a lot of work.
*/ */
plpgsql_push_back_token(tok); plpgsql_push_back_token(tok);
fetch->expr = read_sql_expression2(K_FROM, K_IN, fetch->expr = read_sql_expression2(K_FROM, K_IN,