Re: [HACKERS] Re: IDENTITY/GENERATED v36 Re: Final version of IDENTITY/GENERATED patch - Mailing list pgsql-patches

From Tom Lane
Subject Re: [HACKERS] Re: IDENTITY/GENERATED v36 Re: Final version of IDENTITY/GENERATED patch
Date
Msg-id 14767.1176783980@sss.pgh.pa.us
Whole thread Raw
In response to Re: [HACKERS] Re: IDENTITY/GENERATED v36 Re: Final version of IDENTITY/GENERATED patch  (Andrew Dunstan <andrew@dunslane.net>)
Responses Re: [HACKERS] Re: IDENTITY/GENERATED v36 Re: Final version of IDENTITY/GENERATED patch  (Zoltan Boszormenyi <zb@cybertec.at>)
Re: [HACKERS] Re: IDENTITY/GENERATED v36 Re: Final version of IDENTITY/GENERATED patch  (Andrew Dunstan <andrew@dunslane.net>)
List pgsql-patches
Andrew Dunstan <andrew@dunslane.net> writes:
> Zoltan Boszormenyi wrote:
>> Thanks. This idea solved one of the two shift/reduce conflicts.
>> But the other one can only be solved if I put GENERATED
>> into the reserved_keyword set. But the standard spec says
>> it's unreserved. Now what should I do with it?

> Yeah, I had a brief look. It's a bit ugly - the remaining conflict is in
> the b_expr rules. We do have the filtered_base_yylex() gadget  - not
> sure if that can disambiguate for us.

The problem comes from cases like

    colname coltype DEFAULT 5! GENERATED ...

Since b_expr allows postfix operators, it takes one more token of
lookahead than we have to tell if the default expression is "5!"
or "5!GENERATED ...".

There are basically two ways to fix this:

1. Collapse GENERATED ALWAYS and GENERATED BY into single tokens
using filtered_base_yylex.

2. Stop allowing postfix operators in b_expr.

I find #1 a bit icky --- not only does every case added to
filtered_base_yylex slow down parsing a little more, but combined
tokens create rough spots in the parser's behavior.  As an example,
both NULLS and FIRST are allegedly unreserved words, so this should
work:

regression=# create table nulls (x int);
CREATE TABLE
regression=# select first.* from nulls first;
ERROR:  syntax error at or near "first"
LINE 1: select first.* from nulls first;
                                  ^
regression=#

#2 actually seems like a viable alternative: postfix operators aren't
really in common use, and doing this would not only fix GENERATED but
let us de-reserve a few keywords that are currently reserved.  In a
non-exhaustive check I found that COLLATE, DEFERRABLE, and INITIALLY
could become unreserved_keyword if we take out this production:

*** 7429,7436 ****
                  { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }
              | qual_Op b_expr                    %prec Op
                  { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); }
-             | b_expr qual_Op                    %prec POSTFIXOP
-                 { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); }
              | b_expr IS DISTINCT FROM b_expr        %prec IS
                  {
                    $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2);
--- 7550,7555 ----

(Hmm, actually I'm wondering why COLLATE is a keyword at all right
now... but the other two trace directly to the what-comes-after-DEFAULT
issue.)

            regards, tom lane

pgsql-patches by date:

Previous
From: Andrew Dunstan
Date:
Subject: Re: [HACKERS] Re: IDENTITY/GENERATED v36 Re: Final version of IDENTITY/GENERATED patch
Next
From: "Nikolay Samokhvalov"
Date:
Subject: Re: xpath_array with namespaces support