Re: best way for export gram.y symbols - Mailing list pgsql-hackers
From | Pavel Stehule |
---|---|
Subject | Re: best way for export gram.y symbols |
Date | |
Msg-id | 162867790804031325i98a423cudc0ef1a45b4a491b@mail.gmail.com Whole thread Raw |
In response to | Re: best way for export gram.y symbols (Tom Lane <tgl@sss.pgh.pa.us>) |
Responses |
Re: best way for export gram.y symbols
|
List | pgsql-hackers |
> > > 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 >
pgsql-hackers by date: