Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+76-18
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

+23-10
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)