Commit 9676b010 authored by Tom Lane's avatar Tom Lane

Allow USING and INTO clauses of plpgsql's EXECUTE to appear in either order.

Aside from being more forgiving, this prevents a rather surprising misbehavior
when the "wrong" order was used: the old code didn't throw a syntax error,
but absorbed the INTO clause into the last USING expression, which then did
strange things downstream.

Intentionally not changing the documentation; we'll continue to advertise
only the "standard" clause order.

Backpatch to 8.4, where the USING clause was added to EXECUTE.
parent f4b4a46f
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.143 2010/06/25 16:40:13 tgl Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.144 2010/08/19 18:57:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1642,27 +1642,42 @@ stmt_dynexecute : K_EXECUTE ...@@ -1642,27 +1642,42 @@ stmt_dynexecute : K_EXECUTE
new->row = NULL; new->row = NULL;
new->params = NIL; new->params = NIL;
/* If we found "INTO", collect the argument */ /*
* We loop to allow the INTO and USING clauses to
* appear in either order, since people easily get
* that wrong. This coding also prevents "INTO foo"
* from getting absorbed into a USING expression,
* which is *really* confusing.
*/
for (;;)
{
if (endtoken == K_INTO) if (endtoken == K_INTO)
{ {
if (new->into) /* multiple INTO */
yyerror("syntax error");
new->into = true; new->into = true;
read_into_target(&new->rec, &new->row, &new->strict); read_into_target(&new->rec, &new->row, &new->strict);
endtoken = yylex(); endtoken = yylex();
if (endtoken != ';' && endtoken != K_USING)
yyerror("syntax error");
} }
else if (endtoken == K_USING)
/* If we found "USING", collect the argument(s) */
if (endtoken == K_USING)
{ {
if (new->params) /* multiple USING */
yyerror("syntax error");
do do
{ {
expr = read_sql_expression2(',', ';', expr = read_sql_construct(',', ';', K_INTO,
", or ;", ", or ; or INTO",
&endtoken); "SELECT ",
true, true,
NULL, &endtoken);
new->params = lappend(new->params, expr); new->params = lappend(new->params, expr);
} while (endtoken == ','); } while (endtoken == ',');
} }
else if (endtoken == ';')
break;
else
yyerror("syntax error");
}
$$ = (PLpgSQL_stmt *)new; $$ = (PLpgSQL_stmt *)new;
} }
......
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