Commit 726220fb authored by Tom Lane's avatar Tom Lane

Adjust grammar for plpgsql's OPEN command so that a cursor can be

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.
parent fd97cf4d
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.63 2005/04/05 06:22:14 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.64 2005/04/05 18:05:45 tgl Exp $
--> -->
<chapter id="plpgsql"> <chapter id="plpgsql">
...@@ -2179,19 +2179,21 @@ DECLARE ...@@ -2179,19 +2179,21 @@ DECLARE
</para> </para>
<sect3> <sect3>
<title><command>OPEN FOR SELECT</command></title> <title><command>OPEN FOR</command> <replaceable>query</replaceable></title>
<synopsis> <synopsis>
OPEN <replaceable>unbound_cursor</replaceable> FOR SELECT ...; OPEN <replaceable>unbound_cursor</replaceable> FOR <replaceable>query</replaceable> ;
</synopsis> </synopsis>
<para> <para>
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 execute. The cursor cannot be open already, and it must have been
declared as an unbound cursor (that is, as a simple declared as an unbound cursor (that is, as a simple
<type>refcursor</> variable). The <command>SELECT</command> query <type>refcursor</> variable). The query must be a
is treated in the same way as other <command>SELECT</command> <command>SELECT</command>, or something else that returns rows
statements in <application>PL/pgSQL</>: <application>PL/pgSQL</> (such as <command>EXPLAIN</>). The query
is treated in the same way as other SQL commands in
<application>PL/pgSQL</>: <application>PL/pgSQL</>
variable names are substituted, and the query plan is cached for variable names are substituted, and the query plan is cached for
possible reuse. possible reuse.
</para> </para>
...@@ -2216,7 +2218,7 @@ OPEN <replaceable>unbound_cursor</replaceable> FOR EXECUTE <replaceable class="c ...@@ -2216,7 +2218,7 @@ OPEN <replaceable>unbound_cursor</replaceable> FOR EXECUTE <replaceable class="c
execute. The cursor cannot be open already, and it must have been execute. The cursor cannot be open already, and it must have been
declared as an unbound cursor (that is, as a simple declared as an unbound cursor (that is, as a simple
<type>refcursor</> variable). The query is specified as a string <type>refcursor</> variable). The query is specified as a string
expression in the same way as in the <command>EXECUTE</command> expression, in the same way as in the <command>EXECUTE</command>
command. As usual, this gives flexibility so the query can vary command. As usual, this gives flexibility so the query can vary
from one run to the next. from one run to the next.
</para> </para>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * 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. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -1276,7 +1276,6 @@ stmt_open : K_OPEN lno cursor_varptr ...@@ -1276,7 +1276,6 @@ stmt_open : K_OPEN lno cursor_varptr
if ($3->cursor_explicit_expr == NULL) if ($3->cursor_explicit_expr == NULL)
{ {
tok = yylex(); tok = yylex();
if (tok != K_FOR) if (tok != K_FOR)
{ {
plpgsql_error_lineno = $2; plpgsql_error_lineno = $2;
...@@ -1288,26 +1287,15 @@ stmt_open : K_OPEN lno cursor_varptr ...@@ -1288,26 +1287,15 @@ stmt_open : K_OPEN lno cursor_varptr
} }
tok = yylex(); tok = yylex();
switch (tok) if (tok == K_EXECUTE)
{ {
case K_SELECT: new->dynquery = read_sql_stmt("SELECT ");
case '(': }
plpgsql_push_back_token(tok); else
new->query = read_sql_stmt(""); {
break; plpgsql_push_back_token(tok);
new->query = read_sql_stmt("");
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)));
} }
} }
else else
{ {
...@@ -1316,7 +1304,6 @@ stmt_open : K_OPEN lno cursor_varptr ...@@ -1316,7 +1304,6 @@ stmt_open : K_OPEN lno cursor_varptr
char *cp; char *cp;
tok = yylex(); tok = yylex();
if (tok != '(') if (tok != '(')
{ {
plpgsql_error_lineno = plpgsql_scanner_lineno(); plpgsql_error_lineno = plpgsql_scanner_lineno();
...@@ -1369,7 +1356,6 @@ stmt_open : K_OPEN lno cursor_varptr ...@@ -1369,7 +1356,6 @@ stmt_open : K_OPEN lno cursor_varptr
else else
{ {
tok = yylex(); tok = yylex();
if (tok == '(') if (tok == '(')
{ {
plpgsql_error_lineno = plpgsql_scanner_lineno(); plpgsql_error_lineno = plpgsql_scanner_lineno();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment