Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9676b01

Browse files
committed
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.
1 parent f4b4a46 commit 9676b01

File tree

1 file changed

+34
-19
lines changed

1 file changed

+34
-19
lines changed

src/pl/plpgsql/src/gram.y

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.143 2010/06/25 16:40:13 tgl Exp $
11+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.144 2010/08/19 18:57:57 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1642,26 +1642,41 @@ stmt_dynexecute : K_EXECUTE
16421642
new->row = NULL;
16431643
new->params = NIL;
16441644

1645-
/* If we found "INTO", collect the argument */
1646-
if (endtoken == K_INTO)
1647-
{
1648-
new->into = true;
1649-
read_into_target(&new->rec, &new->row, &new->strict);
1650-
endtoken = yylex();
1651-
if (endtoken != ';' && endtoken != K_USING)
1652-
yyerror("syntax error");
1653-
}
1654-
1655-
/* If we found "USING", collect the argument(s) */
1656-
if (endtoken == K_USING)
1645+
/*
1646+
* We loop to allow the INTO and USING clauses to
1647+
* appear in either order, since people easily get
1648+
* that wrong. This coding also prevents "INTO foo"
1649+
* from getting absorbed into a USING expression,
1650+
* which is *really* confusing.
1651+
*/
1652+
for (;;)
16571653
{
1658-
do
1654+
if (endtoken == K_INTO)
1655+
{
1656+
if (new->into) /* multiple INTO */
1657+
yyerror("syntax error");
1658+
new->into = true;
1659+
read_into_target(&new->rec, &new->row, &new->strict);
1660+
endtoken = yylex();
1661+
}
1662+
else if (endtoken == K_USING)
16591663
{
1660-
expr = read_sql_expression2(',', ';',
1661-
", or ;",
1662-
&endtoken);
1663-
new->params = lappend(new->params, expr);
1664-
} while (endtoken == ',');
1664+
if (new->params) /* multiple USING */
1665+
yyerror("syntax error");
1666+
do
1667+
{
1668+
expr = read_sql_construct(',', ';', K_INTO,
1669+
", or ; or INTO",
1670+
"SELECT ",
1671+
true, true,
1672+
NULL, &endtoken);
1673+
new->params = lappend(new->params, expr);
1674+
} while (endtoken == ',');
1675+
}
1676+
else if (endtoken == ';')
1677+
break;
1678+
else
1679+
yyerror("syntax error");
16651680
}
16661681

16671682
$$ = (PLpgSQL_stmt *)new;

0 commit comments

Comments
 (0)