Pavel Stehule <pavel.steh...@gmail.com> writes: > We should ignore INTO keyword when statement starts with CREATE > keyword. This patch have to simple. I'll prepare it.
I'm already on it... regards, tom lane Index: gram.y =================================================================== RCS file: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v retrieving revision 1.119 diff -c -r1.119 gram.y *** gram.y 7 Jan 2009 13:44:37 -0000 1.119 --- gram.y 2 Feb 2009 19:57:59 -0000 *************** *** 149,155 **** %type <loop_body> loop_body %type <stmt> proc_stmt pl_block %type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit ! %type <stmt> stmt_return stmt_raise stmt_execsql stmt_execsql_insert %type <stmt> stmt_dynexecute stmt_for stmt_perform stmt_getdiag %type <stmt> stmt_open stmt_fetch stmt_move stmt_close stmt_null %type <stmt> stmt_case --- 149,155 ---- %type <loop_body> loop_body %type <stmt> proc_stmt pl_block %type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit ! %type <stmt> stmt_return stmt_raise stmt_execsql %type <stmt> stmt_dynexecute stmt_for stmt_perform stmt_getdiag %type <stmt> stmt_open stmt_fetch stmt_move stmt_close stmt_null %type <stmt> stmt_case *************** *** 646,653 **** { $$ = $1; } | stmt_execsql { $$ = $1; } - | stmt_execsql_insert - { $$ = $1; } | stmt_dynexecute { $$ = $1; } | stmt_perform --- 646,651 ---- *************** *** 1482,1508 **** } ; ! /* this matches any otherwise-unrecognized starting keyword */ ! execsql_start : T_WORD { $$ = pstrdup(yytext); } | T_ERROR { $$ = pstrdup(yytext); } ; - stmt_execsql_insert : K_INSERT lno K_INTO - { - /* - * We have to special-case INSERT so that its INTO - * won't be treated as an INTO-variables clause. - * - * Fortunately, this is the only valid use of INTO - * in a pl/pgsql SQL command, and INTO is already - * a fully reserved word in the main grammar. - */ - $$ = make_execsql_stmt("INSERT INTO", $2); - } - ; - stmt_dynexecute : K_EXECUTE lno { PLpgSQL_stmt_dynexecute *new; --- 1480,1494 ---- } ; ! /* T_WORD+T_ERROR match any otherwise-unrecognized starting keyword */ ! execsql_start : K_INSERT ! { $$ = pstrdup(yytext); } ! | T_WORD { $$ = pstrdup(yytext); } | T_ERROR { $$ = pstrdup(yytext); } ; stmt_dynexecute : K_EXECUTE lno { PLpgSQL_stmt_dynexecute *new; *************** *** 2156,2175 **** PLpgSQL_row *row = NULL; PLpgSQL_rec *rec = NULL; int tok; bool have_into = false; bool have_strict = false; plpgsql_dstring_init(&ds); plpgsql_dstring_append(&ds, sqlstart); for (;;) { tok = yylex(); if (tok == ';') break; if (tok == 0) yyerror("unexpected end of function definition"); ! if (tok == K_INTO) { if (have_into) yyerror("INTO specified more than once"); --- 2142,2177 ---- PLpgSQL_row *row = NULL; PLpgSQL_rec *rec = NULL; int tok; + int prev_tok; bool have_into = false; bool have_strict = false; plpgsql_dstring_init(&ds); plpgsql_dstring_append(&ds, sqlstart); + /* + * We have to special-case the sequence INSERT INTO, because we don't want + * that to be taken as an INTO-variables clause. Fortunately, this is the + * only valid use of INTO in a pl/pgsql SQL command, and INTO is already a + * fully reserved word in the main grammar. We have to treat it that way + * anywhere in the string, not only at the start; consider CREATE RULE + * containing an INSERT statement. + */ + if (pg_strcasecmp(sqlstart, "insert") == 0) + tok = K_INSERT; + else + tok = 0; + for (;;) { + prev_tok = tok; tok = yylex(); if (tok == ';') break; if (tok == 0) yyerror("unexpected end of function definition"); ! ! if (tok == K_INTO && prev_tok != K_INSERT) { if (have_into) yyerror("INTO specified more than once"); -- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs