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  (Tom Lane <tgl@sss.pgh.pa.us>)
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:

Previous
From: Bernd Helmle
Date:
Subject: Re: Separate psql commands from arguments (was: psql command aliases support)
Next
From: Mark Mielke
Date:
Subject: Re: [GENERAL] SHA1 on postgres 8.3