>
>
> No, you don't.  Whatever you think you need those for, there's probably
>  a better way to do it.  We got out of the business of letting anything
>  but scan.c and gram.c depend on Bison symbol numbers years ago, and
>  I don't much want to re-introduce that dependency.
>
>  What exactly are you trying to accomplish?

when I build CASE expression, I have to merge some PLpgSQL_expr
together. Then I have to reparse expr->query and I have to find params
and actualize it.
I found some else. I can't include parser/parse.h in gram.y file,
because there is name's conflict. But I can do it in other file. It's
better, because is less risk of wrong preproces. So I have function:

#include "parser/parse.h"
#include "parser/gramparse.h"

extern char *base_yytext;

int
plpgsql_querylex(int *param, char **ttext)
{
        int     tok = base_yylex();

        if (tok == 0)
                return PLPGSQL_QUERYLEX_DONE;

        *ttext = base_yytext;
        switch (tok)
        {
                case SELECT:
                        return PLPGSQL_QUERYLEX_SELECT;

                case PARAM:
                        *param = base_yylval.ival;
                        return PLPGSQL_QUERYLEX_PARAM;

                default:
                        return PLPGSQL_QUERYLEX_NONPARAM;
        }
}


and then I can merge queries in function:
/*
 * This function joins an PLpgSQL_expr to expression stack. It's used
 * for CASE statement where from some expr is created one expression.
 * Reparsing is necessary for detecting parameters in SQL query.
 */
static void
add_expr(PLpgSQL_expr *expr, PLpgSQL_dstring *ds, int *nparams, int *params)
{
        char    buff[32];
        int                     lex;
        int             pnum;
        char    *yytext;


        scanner_init(expr->query);

        /* First lexem have to be SELECT */
        if (plpgsql_querylex(&pnum, &yytext) != PLPGSQL_QUERYLEX_SELECT)
        {
                plpgsql_error_lineno = plpgsql_scanner_lineno();
                /* internal error */
                elog(ERROR, "expected \"SELECT \", got \"%s\"",
                                                            yytext);
        }

        while((lex = plpgsql_querylex(&pnum, &yytext)) != PLPGSQL_QUERYLEX_DONE)
        {
                if (lex == PLPGSQL_QUERYLEX_PARAM)
                {
                        int dno;
                        int     i;

                        if (pnum < 1 || pnum >= MAX_EXPR_PARAMS)
                                elog(ERROR, "parsing query failure,
wrong param $%d", pnum);

                        dno = expr->params[pnum-1];
                        for (i = 0; i < *nparams; i++)
                                if (params[i] == dno)
                                        break;

                        snprintf(buff, sizeof(buff), "$%d", i+1);
                        /* when not found variable */
                        if (i >= *nparams)
                        {
                                if (*nparams >= MAX_EXPR_PARAMS)
                                {
                                        plpgsql_error_lineno =
plpgsql_scanner_lineno();
                                        ereport(ERROR,

(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                                                 errmsg("too many
variables specified in SQL statement")));
                                }
                                params[*nparams] = dno;
                                (*nparams)++;
                        }
                        plpgsql_dstring_append(ds, buff);
                }
                else
                        plpgsql_dstring_append(ds, yytext);
        }

        scanner_finish();
}

Regards
Pavel Stehule

>
>                         regards, tom lane
>

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to