Обсуждение: Module extension for parsing and rewriting functions with infixed syntax

Поиск
Список
Период
Сортировка

Module extension for parsing and rewriting functions with infixed syntax

От
Thomas Girault
Дата:
Hello,

I am working on a PostgreSQL extension module which defines new
grammar rules completing the classical SQL syntax defined in the
src/backend/parser/gram.y file.

Basically, I want to handle predicates having an infixed syntax { X IS
Y } and rewrite them as classical Boolean functions with prefixed
syntax { Y(X) }.

For instance, the following query :SELECT * FROM cars WHERE cars.color IS yellow;
would be rewritten into :SELECT * FROM cars WHERE yellow(cars.color);

The new predicate could be rewritten as a plpgsql Boolean function
with an unique argument (cars.color IS yellow --> yellow(cars.color)).
I have then added the following rule to the "func_expr" definition
(see gram.y:10280 in postgresql-9.1beta3 source code) :

func_expr:
...| func_arg_expr IS func_name over_clause    {        FuncCall *n = makeNode(FuncCall);        n->funcname = $3;
 n->args = list_make1($1);        n->agg_order = NIL;        n->agg_star = FALSE;        n->agg_distinct = FALSE;
n->func_variadic = FALSE;        n->over = $4;        n->location = @1;        $$ = (Node *)n;    }
 
...

However, my first attempt leads to the following errors :/usr/bin/bison -d  -o gram.c gram.ygram.y: conflicts: 84
shift/reduce,807 reduce/reducegram.y: expected 0 shift/reduce conflictsgram.y: expected 0 reduce/reduce conflicts
 

How can I avoid this kind of errors without changing the entire grammar?

In addition, I would rather making this new functionality independent
of the original PostgreSQL source code.
Ideally, the new defined bison rules would be defined in an autonomous
module extension.
I have seen that some contrib modules (such as SEG or CUBE) define
separate bison grammar rules.
However, I don't understand yet how such rules integrate with the
gram.y file without any conflicts.

Can I define my new bison rules separately of the gram.y file?
Can I use the new functionality dynamically after loading an extension
module (LOAD 'MY_EXTENSION';)?


I am new in the PostgreSQL community and any ideas for solving these
problems would be very helpful.

Thanks by advance,

Thomas Girault


Re: Module extension for parsing and rewriting functions with infixed syntax

От
Tom Lane
Дата:
Thomas Girault <toma.girault@gmail.com> writes:
> func_expr:
> ...
>     | func_arg_expr IS func_name over_clause

> However, my first attempt leads to the following errors :
>     /usr/bin/bison -d  -o gram.c gram.y
>     gram.y: conflicts: 84 shift/reduce, 807 reduce/reduce
>     gram.y: expected 0 shift/reduce conflicts
>     gram.y: expected 0 reduce/reduce conflicts

Most likely, you need to think about how to distinguish this case from
IS NULL, IS TRUE, and the other things that can follow IS already.
I don't think all those words are considered fully reserved today,
but they'd have to be (or at least not be allowed as func_names)
to make this non-ambiguous.  Looking at bison -v output will help
you figure out for sure what it thinks is ambiguous.

> In addition, I would rather making this new functionality independent
> of the original PostgreSQL source code.
> Ideally, the new defined bison rules would be defined in an autonomous
> module extension.

Bison doesn't support that; it needs to see the entire grammar at once.

(Many years ago I worked with systems at HP that did have run-time-
extensible parsers.  They were a pain: not all that flexible, and it
was easy to get grammar bugs wherein things parsed some other way than
you expected.  To me the main value of bison is that it tells you about
it when you wrote something ambiguous; and for that, it really has to
see all the rules not just some of them.)

> I have seen that some contrib modules (such as SEG or CUBE) define
> separate bison grammar rules.

Those grammars have nothing to do with parsing SQL; they're just used to
parse literal values of those data types.

> Can I define my new bison rules separately of the gram.y file?
> Can I use the new functionality dynamically after loading an extension
> module (LOAD 'MY_EXTENSION';)?

No, and no.
        regards, tom lane