Re: BUG #4629: PL/pgSQL issue - Mailing list pgsql-bugs

From Pavel Stehule
Subject Re: BUG #4629: PL/pgSQL issue
Date
Msg-id 162867790902021227i46e2f07qb1a09bd0c9aaabec@mail.gmail.com
Whole thread Raw
In response to Re: BUG #4629: PL/pgSQL issue  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs
2009/2/2 Tom Lane <tgl@sss.pgh.pa.us>:
> Pavel Stehule <pavel.stehule@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

ok
Regards
Pavel Stehule

>
> 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");
>

pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: BUG #4629: PL/pgSQL issue
Next
From: Tom Lane
Date:
Subject: Re: BUG #4635: postgres.exe crash when RAISE NOTICE during debugging of PL/pgSQL function in PgAdminIII