Adjust grammar for plpgsql's OPEN command so that a cursor can be
authorTom Lane
Tue, 5 Apr 2005 18:05:46 +0000 (18:05 +0000)
committerTom Lane
Tue, 5 Apr 2005 18:05:46 +0000 (18:05 +0000)
OPENed on non-SELECT commands such as EXPLAIN or SHOW (anything that
returns tuples is allowed).  This flexibility already existed for
bound cursors, but OPEN was artificially restricting what it would
take.  Per a gripe some months back.

doc/src/sgml/plpgsql.sgml
src/pl/plpgsql/src/gram.y

index bd6f0254c3aeb1325d9498fdc32349ae91015bec..3ea1ac19b2dc13858cb50293f2e94a1855d887aa 100644 (file)
@@ -1,5 +1,5 @@
 
 
  
@@ -2179,19 +2179,21 @@ DECLARE
     
 
     
-     <command>OPEN FOR<span class="marked"> SELECT</command</span>>
+     <command>OPEN FOR<span class="marked"></command> <replaceable>query</replaceable</span>>
 
 
-OPEN unbound_cursor FOR SELECT ...;
+OPEN unbound_cursor FOR query ;
 
 
        
-    The cursor variable is opened and given the specified query to
+        The cursor variable is opened and given the specified query to
         execute.  The cursor cannot be open already, and it must have been
         declared as an unbound cursor (that is, as a simple
-        refcursor variable).  The SELECT query
-        is treated in the same way as other SELECT
-        statements in PL/pgSQL: PL/pgSQL
+        refcursor variable).  The query must be a
+        SELECT, or something else that returns rows
+        (such as EXPLAIN).  The query
+        is treated in the same way as other SQL commands in
+        PL/pgSQL: PL/pgSQL
         variable names are substituted, and the query plan is cached for
         possible reuse.
        
@@ -2216,7 +2218,7 @@ OPEN unbound_cursor FOR EXECUTE 
           execute.  The cursor cannot be open already, and it must have been
           declared as an unbound cursor (that is, as a simple
           refcursor variable).  The query is specified as a string
-          expression in the same way as in the EXECUTE
+          expression, in the same way as in the EXECUTE
           command.  As usual, this gives flexibility so the query can vary
           from one run to the next.
        
index e2b5c7aab146cec04f840649e5bcb26dba40fdfc..65b8f5f409329fa601da396792954ffee82184f9 100644 (file)
@@ -4,7 +4,7 @@
  *                       procedural language
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.67 2005/04/05 06:22:16 tgl Exp $
+ *   $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.68 2005/04/05 18:05:46 tgl Exp $
  *
  *   This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -1276,7 +1276,6 @@ stmt_open     : K_OPEN lno cursor_varptr
                        if ($3->cursor_explicit_expr == NULL)
                        {
                            tok = yylex();
-
                            if (tok != K_FOR)
                            {
                                plpgsql_error_lineno = $2;
@@ -1288,26 +1287,15 @@ stmt_open       : K_OPEN lno cursor_varptr
                            }
 
                            tok = yylex();
-                           switch (tok)
+                           if (tok == K_EXECUTE)
                            {
-                               case K_SELECT:
-                               case '(':
-                                   plpgsql_push_back_token(tok);
-                                   new->query = read_sql_stmt("");
-                                   break;
-
-                               case K_EXECUTE:
-                                   new->dynquery = read_sql_stmt("SELECT ");
-                                   break;
-
-                               default:
-                                   plpgsql_error_lineno = $2;
-                                   ereport(ERROR,
-                                           (errcode(ERRCODE_SYNTAX_ERROR),
-                                            errmsg("syntax error at \"%s\"",
-                                                   yytext)));
+                               new->dynquery = read_sql_stmt("SELECT ");
+                           }
+                           else
+                           {
+                               plpgsql_push_back_token(tok);
+                               new->query = read_sql_stmt("");
                            }
-
                        }
                        else
                        {
@@ -1316,7 +1304,6 @@ stmt_open     : K_OPEN lno cursor_varptr
                                char   *cp;
 
                                tok = yylex();
-
                                if (tok != '(')
                                {
                                    plpgsql_error_lineno = plpgsql_scanner_lineno();
@@ -1369,7 +1356,6 @@ stmt_open     : K_OPEN lno cursor_varptr
                            else
                            {
                                tok = yylex();
-
                                if (tok == '(')
                                {
                                    plpgsql_error_lineno = plpgsql_scanner_lineno();