Re: [PATCHES] Continue stmt for plpgsql

2005-06-21 Thread Neil Conway

Neil Conway wrote:

Attached is a revised patch.


Patch applied -- thanks, Pavel. I ended up using ERRCODE_SYNTAX_ERROR 
when a CONTINUE is specified outside a loop. BTW, one minor annoyance is:


<>
BEGIN
LOOP
CONTINUE lbl;
END LOOP;
END;

The current implementation will raise an error, as it should, but it 
does so at runtime, and claims that "CONTINUE cannot be used outside a 
loop". We could fix this by dividing labels into "block labels" and 
"loop labels" at compile-time and only accepting a loop label for 
CONTINUE, but I haven't implemented this yet.


-Neil

---(end of broadcast)---
TIP 6: Have you searched our list archives?

  http://archives.postgresql.org


Re: [PATCHES] Continue stmt for plpgsql

2005-06-21 Thread Neil Conway

Pavel Stehule wrote:
  Attached patch provide continue stmt in plpgsql language. Continue stmt 
start new step in any loop stmt. If stmt continue is in begin end block, 
then find first outer loop (per recent discussion).


Attached is a revised patch. I didn't see anything major that needed to 
be corrected, but there were some minor cleanups to be made. I also 
clarified the error message when a CONTINUE is specified outside a loop 
(although I wasn't quite sure what error message to use: SYNTAX_ERROR 
seems a bit weird, as the problem isn't detected until the end of the 
function's execution. I'm using PLPGSQL_ERROR at the moment, but 
suggestions for a better choice are welcome).


Barring any objections, I'll apply this tomorrow.

-Neil
Index: doc/src/sgml/plpgsql.sgml
===
RCS file: /var/lib/cvs/pgsql/doc/src/sgml/plpgsql.sgml,v
retrieving revision 1.73
diff -c -r1.73 plpgsql.sgml
*** doc/src/sgml/plpgsql.sgml	19 Jun 2005 23:39:05 -	1.73
--- doc/src/sgml/plpgsql.sgml	21 Jun 2005 08:46:27 -
***
*** 1779,1788 
  
  
  
!  With the LOOP, EXIT, WHILE,
!  and FOR statements, you can arrange for your
!  PL/pgSQL function to repeat a series
!  of commands.
  
  
  
--- 1779,1788 
  
  
  
!  With the LOOP, EXIT,
!  CONTINUE, WHILE, and FOR
!  statements, you can arrange for your PL/pgSQL
!  function to repeat a series of commands.
  
  
  
***
*** 1807,1836 
   
EXIT
  
  
  EXIT  label   WHEN expression ;
  
  
 
! If no label is given,
! the innermost loop is terminated and the
! statement following END LOOP is executed next.
! If label is given, it
! must be the label of the current or some outer level of nested loop
! or block. Then the named loop or block is terminated and control
! continues with the statement after the loop's/block's corresponding
! END.
 
  
 
! If WHEN is present, loop exit occurs only if the specified
! condition is true, otherwise control passes to the statement after
! EXIT.
 
  
 
! EXIT can be used to cause early exit from all types of
! loops; it is not limited to use with unconditional loops.
 
  
 
--- 1807,1842 
   
EXIT
  
+  
+   EXIT
+   in PL/pgSQL
+  
+ 
  
  EXIT  label   WHEN expression ;
  
  
 
! If no label is given, the innermost
! loop is terminated and the statement following END
! LOOP is executed next.  If label
! is given, it must be the label of the current or some outer
! level of nested loop or block. Then the named loop or block is
! terminated and control continues with the statement after the
! loop's/block's corresponding END.
 
  
 
! If WHEN is specified, the loop exit occurs only if
! expression is true. Otherwise, control passes
! to the statement after EXIT.
 
  
 
! EXIT can be used with all types of loops; it is
! not limited to use with unconditional loops. When used with a
! BEGIN block, EXIT passes
! control to the next statement after the end of the block.
 
  
 
***
*** 1859,1866 
--- 1865,1924 
   
  
   
+   CONTINUE
+ 
+  
+   CONTINUE
+   in PL/pgSQL
+  
+ 
+ 
+ CONTINUE  label   WHEN expression ;
+ 
+ 
+
+ If no label is given, the next iteration of
+ the innermost loop is begun. That is, control is passed back
+ to the loop control expression (if any), and the body of the
+ loop is re-evaluated. If label is present, it
+ specifies the label of the loop whose execution will be
+ continued.
+
+ 
+
+ If WHEN is specified, the next iteration of the
+ loop is begun only if expression is
+ true. Otherwise, control passes to the statement after
+ CONTINUE.
+
+ 
+
+ CONTINUE can be used with all types of loops; it
+ is not limited to use with unconditional loops.
+
+ 
+
+ Examples:
+ 
+ LOOP
+ -- some computations
+ EXIT WHEN count > 100;
+ CONTINUE WHEN count < 50;
+ -- some computations for count IN [50 .. 100] 
+ END LOOP;
+ 
+
+  
+ 
+ 
+  
WHILE
  
+  
+   WHILE
+   in PL/pgSQL
+  
+ 
  
  <

[PATCHES] Continue stmt for plpgsql

2005-06-17 Thread Pavel Stehule
Hello

  Attached patch provide continue stmt in plpgsql language. Continue stmt 
start new step in any loop stmt. If stmt continue is in begin end block, 
then find first outer loop (per recent discussion).

Regards
Pavel Stehule
diff -c -r --new-file pgsql/doc/src/sgml/plpgsql.sgml 
pgsql.00/doc/src/sgml/plpgsql.sgml
*** pgsql/doc/src/sgml/plpgsql.sgml 2005-06-17 06:53:03.0 +0200
--- pgsql.00/doc/src/sgml/plpgsql.sgml  2005-06-17 10:00:15.0 +0200
***
*** 1859,1864 
--- 1859,1904 
   
  
   
+   CONTINUE
+ 
+ 
+ CONTINUE  label   
WHEN expression ;
+ 
+ 
+
+ If no label is given,
+ the innermost loop is executed again (if all relevant 
+   condition expression evaluates to true). If 
label 
+   is given, it must be the label of the current or some outer level of 
nested loop
+ Then the named loop is evaluated again.
+
+ 
+
+ If WHEN is present, loop continue occurs only if the 
specified
+ condition is true, otherwise control passes to the statement after
+ CONTINUE.
+
+ 
+
+ CONTINUE can be used to cause early exit from all types of
+ loops; it is not limited to use with unconditional loops.
+
+ 
+
+ Examples:
+ 
+ LOOP
+ -- some computations
+ EXIT WHEN count > 100;
+ CONTINUE WHEN count < 50;
+ -- some computations for count IN [50 .. 100] 
+ END LOOP;
+ 
+
+  
+ 
+ 
+  
WHILE
  
  
diff -c -r --new-file pgsql/src/pl/plpgsql/src/gram.y 
pgsql.00/src/pl/plpgsql/src/gram.y
*** pgsql/src/pl/plpgsql/src/gram.y 2005-06-17 06:53:56.0 +0200
--- pgsql.00/src/pl/plpgsql/src/gram.y  2005-06-17 08:39:10.0 +0200
***
*** 130,135 
--- 130,137 
  %type   stmt_dynexecute stmt_getdiag
  %type   stmt_open stmt_fetch stmt_close stmt_null
  
+ %type   exit_type
+ 
  %type   proc_exceptions
  %type  exception_sect
  %type  proc_exception
***
*** 153,158 
--- 155,161 
  %tokenK_BEGIN
  %tokenK_CLOSE
  %tokenK_CONSTANT
+ %tokenK_CONTINUE
  %tokenK_CURSOR
  %tokenK_DEBUG
  %tokenK_DECLARE
***
*** 1035,1046 
}
;
  
! stmt_exit : K_EXIT lno opt_exitlabel opt_exitcond
{
PLpgSQL_stmt_exit *new;
  
new = 
palloc0(sizeof(PLpgSQL_stmt_exit));
new->cmd_type = 
PLPGSQL_STMT_EXIT;
new->lineno   = $2;
new->label= $3;
new->cond = $4;
--- 1038,1050 
}
;
  
! stmt_exit : exit_type lno opt_exitlabel opt_exitcond
{
PLpgSQL_stmt_exit *new;
  
new = 
palloc0(sizeof(PLpgSQL_stmt_exit));
new->cmd_type = 
PLPGSQL_STMT_EXIT;
+   new->exit_type = $1;
new->lineno   = $2;
new->label= $3;
new->cond = $4;
***
*** 1049,1054 
--- 1053,1068 
}
;
  
+ exit_type : K_EXIT
+   {
+   $$ = 0;
+   }
+   | K_CONTINUE
+   {
+   $$ = 1;
+   }
+   ;
+ 
  stmt_return   : K_RETURN lno
{
PLpgSQL_stmt_return *new;
diff -c -r --new-file pgsql/src/pl/plpgsql/src/pl_exec.c 
pgsql.00/src/pl/plpgsql/src/pl_exec.c
*** pgsql/src/pl/plpgsql/src/pl_exec.c  2005-06-17 06:53:56.0 +0200
--- pgsql.00/src/pl/plpgsql/src/pl_exec.c   2005-06-17 09:04:55.0 
+0200
***
*** 917,923 
{
case PLPGSQL_RC_OK:
return PLPGSQL_RC_OK;
! 
case PLPGSQL_RC_EXIT:
if (estate->exitlabel == NULL)
return PLPGSQL_RC_OK;
--- 917,923 
{
case PLPGSQL_RC_OK:
return PLPGSQL_RC_OK;
!