Lists: | pgsql-hackers |
---|
From: | "Pavel Stehule" <pavel(dot)stehule(at)gmail(dot)com> |
---|---|
To: | "PG Hackers" <pgsql-hackers(at)postgresql(dot)org> |
Subject: | best way for export gram.y symbols |
Date: | 2008-04-03 17:36:52 |
Message-ID: | 162867790804031036o7a4dd76bw504b4653b3734ed4@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
Hello
I would to use main scanner from plpgsql. I need some values from parser/parse.h
#define SELECT 543
#define PARAM 642
and YYSTYPE
any ideas how to do it?
I would not copy it by hand.
Regards
Pavel Stehule
From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | "Pavel Stehule" <pavel(dot)stehule(at)gmail(dot)com> |
Cc: | "PG Hackers" <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: best way for export gram.y symbols |
Date: | 2008-04-03 18:53:33 |
Message-ID: | 6459.1207248813@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
"Pavel Stehule" <pavel(dot)stehule(at)gmail(dot)com> writes:
> I would to use main scanner from plpgsql. I need some values from parser/parse.h
> #define SELECT 543
> #define PARAM 642
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?
regards, tom lane
From: | "Pavel Stehule" <pavel(dot)stehule(at)gmail(dot)com> |
---|---|
To: | "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | "PG Hackers" <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: best way for export gram.y symbols |
Date: | 2008-04-03 20:25:11 |
Message-ID: | 162867790804031325i98a423cudc0ef1a45b4a491b@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | 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 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
>
From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | "Pavel Stehule" <pavel(dot)stehule(at)gmail(dot)com> |
Cc: | "PG Hackers" <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: best way for export gram.y symbols |
Date: | 2008-04-03 21:33:11 |
Message-ID: | 23279.1207258391@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
"Pavel Stehule" <pavel(dot)stehule(at)gmail(dot)com> writes:
>> 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.
There has to be a better way than that. What CASE syntax are you
trying to implement, anyhow?
regards, tom lane
From: | "Pavel Stehule" <pavel(dot)stehule(at)gmail(dot)com> |
---|---|
To: | "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | "PG Hackers" <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: best way for export gram.y symbols |
Date: | 2008-04-04 05:43:30 |
Message-ID: | 162867790804032243r7078d8fanc8450c3ab8196224@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Lists: | pgsql-hackers |
On 03/04/2008, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> "Pavel Stehule" <pavel(dot)stehule(at)gmail(dot)com> writes:
> >> 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.
>
> There has to be a better way than that. What CASE syntax are you
> trying to implement, anyhow?
CASE expr
WHEN expr [,expr[,...]] THEN
statements list
END CASE;
CASE
WHEN expr THEN
statements list
WHEN ....
END CASE;
I would to remove repeated evaluation and casting. Transformation to
SQL case statement is simply and fast. I had to add one file to
plpgsql code, but I haven't any redundant code and code is readable
and simple. But any ideas are welcome.
Current patch is in attachment
>
> regards, tom lane
>
Attachment | Content-Type | Size |
---|---|---|
plpgsql_case.diff | text/x-patch | 18.5 KB |
pl_querylex.c | text/x-csrc | 953 bytes |