>
>
> 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
createdone 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
queryfailure,
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
>