Skip to content

Commit ebcb4c9

Browse files
author
Neil Conway
committed
Add a CONTINUE statement to PL/PgSQL, which can be used to begin the
next iteration of a loop. Update documentation and add regression tests. Patch from Pavel Stehule, reviewed by Neil Conway.
1 parent 7a28de2 commit ebcb4c9

File tree

8 files changed

+501
-80
lines changed

8 files changed

+501
-80
lines changed

doc/src/sgml/plpgsql.sgml

Lines changed: 76 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.73 2005/06/19 23:39:05 neilc Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.74 2005/06/22 01:35:02 neilc Exp $
33
-->
44

55
<chapter id="plpgsql">
@@ -1779,10 +1779,10 @@ END IF;
17791779
</indexterm>
17801780

17811781
<para>
1782-
With the <literal>LOOP</>, <literal>EXIT</>, <literal>WHILE</>,
1783-
and <literal>FOR</> statements, you can arrange for your
1784-
<application>PL/pgSQL</application> function to repeat a series
1785-
of commands.
1782+
With the <literal>LOOP</>, <literal>EXIT</>,
1783+
<literal>CONTINUE</>, <literal>WHILE</>, and <literal>FOR</>
1784+
statements, you can arrange for your <application>PL/pgSQL</>
1785+
function to repeat a series of commands.
17861786
</para>
17871787

17881788
<sect3>
@@ -1807,30 +1807,36 @@ END LOOP;
18071807
<sect3>
18081808
<title><literal>EXIT</></title>
18091809

1810+
<indexterm>
1811+
<primary>EXIT</primary>
1812+
<secondary>in PL/pgSQL</secondary>
1813+
</indexterm>
1814+
18101815
<synopsis>
18111816
EXIT <optional> <replaceable>label</replaceable> </optional> <optional> WHEN <replaceable>expression</replaceable> </optional>;
18121817
</synopsis>
18131818

18141819
<para>
1815-
If no <replaceable>label</replaceable> is given,
1816-
the innermost loop is terminated and the
1817-
statement following <literal>END LOOP</> is executed next.
1818-
If <replaceable>label</replaceable> is given, it
1819-
must be the label of the current or some outer level of nested loop
1820-
or block. Then the named loop or block is terminated and control
1821-
continues with the statement after the loop's/block's corresponding
1822-
<literal>END</>.
1820+
If no <replaceable>label</replaceable> is given, the innermost
1821+
loop is terminated and the statement following <literal>END
1822+
LOOP</> is executed next. If <replaceable>label</replaceable>
1823+
is given, it must be the label of the current or some outer
1824+
level of nested loop or block. Then the named loop or block is
1825+
terminated and control continues with the statement after the
1826+
loop's/block's corresponding <literal>END</>.
18231827
</para>
18241828

18251829
<para>
1826-
If <literal>WHEN</> is present, loop exit occurs only if the specified
1827-
condition is true, otherwise control passes to the statement after
1828-
<literal>EXIT</>.
1830+
If <literal>WHEN</> is specified, the loop exit occurs only if
1831+
<replaceable>expression</> is true. Otherwise, control passes
1832+
to the statement after <literal>EXIT</>.
18291833
</para>
18301834

18311835
<para>
1832-
<literal>EXIT</> can be used to cause early exit from all types of
1833-
loops; it is not limited to use with unconditional loops.
1836+
<literal>EXIT</> can be used with all types of loops; it is
1837+
not limited to use with unconditional loops. When used with a
1838+
<literal>BEGIN</literal> block, <literal>EXIT</literal> passes
1839+
control to the next statement after the end of the block.
18341840
</para>
18351841

18361842
<para>
@@ -1858,9 +1864,61 @@ END;
18581864
</para>
18591865
</sect3>
18601866

1867+
<sect3>
1868+
<title><literal>CONTINUE</></title>
1869+
1870+
<indexterm>
1871+
<primary>CONTINUE</primary>
1872+
<secondary>in PL/pgSQL</secondary>
1873+
</indexterm>
1874+
1875+
<synopsis>
1876+
CONTINUE <optional> <replaceable>label</replaceable> </optional> <optional> WHEN <replaceable>expression</replaceable> </optional>;
1877+
</synopsis>
1878+
1879+
<para>
1880+
If no <replaceable>label</> is given, the next iteration of
1881+
the innermost loop is begun. That is, control is passed back
1882+
to the loop control expression (if any), and the body of the
1883+
loop is re-evaluated. If <replaceable>label</> is present, it
1884+
specifies the label of the loop whose execution will be
1885+
continued.
1886+
</para>
1887+
1888+
<para>
1889+
If <literal>WHEN</> is specified, the next iteration of the
1890+
loop is begun only if <replaceable>expression</> is
1891+
true. Otherwise, control passes to the statement after
1892+
<literal>CONTINUE</>.
1893+
</para>
1894+
1895+
<para>
1896+
<literal>CONTINUE</> can be used with all types of loops; it
1897+
is not limited to use with unconditional loops.
1898+
</para>
1899+
1900+
<para>
1901+
Examples:
1902+
<programlisting>
1903+
LOOP
1904+
-- some computations
1905+
EXIT WHEN count &gt; 100;
1906+
CONTINUE WHEN count &lt; 50;
1907+
-- some computations for count IN [50 .. 100]
1908+
END LOOP;
1909+
</programlisting>
1910+
</para>
1911+
</sect3>
1912+
1913+
18611914
<sect3>
18621915
<title><literal>WHILE</></title>
18631916

1917+
<indexterm>
1918+
<primary>WHILE</primary>
1919+
<secondary>in PL/pgSQL</secondary>
1920+
</indexterm>
1921+
18641922
<synopsis>
18651923
<optional>&lt;&lt;<replaceable>label</replaceable>&gt;&gt;</optional>
18661924
WHILE <replaceable>expression</replaceable> LOOP

src/pl/plpgsql/src/gram.y

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* procedural language
55
*
66
* IDENTIFICATION
7-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.76 2005/06/14 06:43:14 neilc Exp $
7+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.77 2005/06/22 01:35:02 neilc Exp $
88
*
99
* This software is copyrighted by Jan Wieck - Hamburg.
1010
*
@@ -61,6 +61,7 @@ static void plpgsql_sql_error_callback(void *arg);
6161

6262
%union {
6363
int32 ival;
64+
bool boolean;
6465
char *str;
6566
struct
6667
{
@@ -100,7 +101,7 @@ static void plpgsql_sql_error_callback(void *arg);
100101
%type <declhdr> decl_sect
101102
%type <varname> decl_varname
102103
%type <str> decl_renname
103-
%type <ival> decl_const decl_notnull
104+
%type <boolean> decl_const decl_notnull exit_type
104105
%type <expr> decl_defval decl_cursor_query
105106
%type <dtype> decl_datatype
106107
%type <row> decl_cursor_args
@@ -153,6 +154,7 @@ static void plpgsql_sql_error_callback(void *arg);
153154
%token K_BEGIN
154155
%token K_CLOSE
155156
%token K_CONSTANT
157+
%token K_CONTINUE
156158
%token K_CURSOR
157159
%token K_DEBUG
158160
%token K_DECLARE
@@ -514,9 +516,9 @@ decl_renname : T_WORD
514516
;
515517

516518
decl_const :
517-
{ $$ = 0; }
519+
{ $$ = false; }
518520
| K_CONSTANT
519-
{ $$ = 1; }
521+
{ $$ = true; }
520522
;
521523

522524
decl_datatype :
@@ -531,9 +533,9 @@ decl_datatype :
531533
;
532534

533535
decl_notnull :
534-
{ $$ = 0; }
536+
{ $$ = false; }
535537
| K_NOT K_NULL
536-
{ $$ = 1; }
538+
{ $$ = true; }
537539
;
538540

539541
decl_defval : ';'
@@ -1035,29 +1037,40 @@ stmt_select : K_SELECT lno
10351037
}
10361038
;
10371039

1038-
stmt_exit : K_EXIT lno opt_exitlabel opt_exitcond
1040+
stmt_exit : exit_type lno opt_exitlabel opt_exitcond
10391041
{
10401042
PLpgSQL_stmt_exit *new;
10411043

10421044
new = palloc0(sizeof(PLpgSQL_stmt_exit));
10431045
new->cmd_type = PLPGSQL_STMT_EXIT;
1044-
new->lineno = $2;
1046+
new->is_exit = $1;
1047+
new->lineno = $2;
10451048
new->label = $3;
10461049
new->cond = $4;
10471050

10481051
$$ = (PLpgSQL_stmt *)new;
10491052
}
10501053
;
10511054

1055+
exit_type : K_EXIT
1056+
{
1057+
$$ = true;
1058+
}
1059+
| K_CONTINUE
1060+
{
1061+
$$ = false;
1062+
}
1063+
;
1064+
10521065
stmt_return : K_RETURN lno
10531066
{
10541067
PLpgSQL_stmt_return *new;
10551068

10561069
new = palloc0(sizeof(PLpgSQL_stmt_return));
10571070
new->cmd_type = PLPGSQL_STMT_RETURN;
10581071
new->lineno = $2;
1059-
new->expr = NULL;
1060-
new->retvarno = -1;
1072+
new->expr = NULL;
1073+
new->retvarno = -1;
10611074

10621075
if (plpgsql_curr_compile->fn_retset)
10631076
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy