mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
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.
This commit is contained in:
parent
f4b4a46f01
commit
9676b01028
@ -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
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user