*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.125 2009/06/18 10:22:09 petere Exp $
+ * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.125.2.1 2010/08/19 18:58:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
new->row = NULL;
new->params = NIL;
- /* If we found "INTO", collect the argument */
- if (endtoken == K_INTO)
- {
- new->into = true;
- read_into_target(&new->rec, &new->row, &new->strict);
- endtoken = yylex();
- if (endtoken != ';' && endtoken != K_USING)
- yyerror("syntax error");
- }
-
- /* If we found "USING", collect the argument(s) */
- if (endtoken == K_USING)
+ /*
+ * 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 (;;)
{
- do
+ if (endtoken == K_INTO)
+ {
+ if (new->into) /* multiple INTO */
+ yyerror("syntax error");
+ new->into = true;
+ read_into_target(&new->rec, &new->row, &new->strict);
+ endtoken = yylex();
+ }
+ else if (endtoken == K_USING)
{
- expr = read_sql_expression2(',', ';',
- ", or ;",
- &endtoken);
- new->params = lappend(new->params, expr);
- } while (endtoken == ',');
+ if (new->params) /* multiple USING */
+ yyerror("syntax error");
+ do
+ {
+ expr = read_sql_construct(',', ';', K_INTO,
+ ", or ; or INTO",
+ "SELECT ",
+ true, true,
+ &endtoken);
+ new->params = lappend(new->params, expr);
+ } while (endtoken == ',');
+ }
+ else if (endtoken == ';')
+ break;
+ else
+ yyerror("syntax error");
}
$$ = (PLpgSQL_stmt *)new;