Re: operator exclusion constraints

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Jeff Davis <pgsql(at)j-davis(dot)com>
Cc: Robert Haas <robertmhaas(at)gmail(dot)com>, Peter Eisentraut <peter_e(at)gmx(dot)net>, Simon Riggs <simon(at)2ndquadrant(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: operator exclusion constraints
Date: 2009-11-07 02:20:12
Message-ID: 12888.1257560412@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Jeff Davis <pgsql(at)j-davis(dot)com> writes:
> On Fri, 2009-11-06 at 19:05 -0500, Tom Lane wrote:
>> Maybe I'm missing
>> something. What's your grammar patch exactly, and what does
>> bison -v finger as being the problem?

> bison -v doesn't show anything useful beyond saying that there is one
> shift/reduce conflict. The gram.output is 10MB, which doesn't help me
> much (I'm still trying to make sense of it).

Well, you need to learn a bit more about bison I think. The complaint
is

State 1135 conflicts: 1 shift/reduce

so we look at state 1135, which says:

state 1135

241 alter_table_cmd: ADD_P . opt_column columnDef
251 | ADD_P . TableConstraint

CHECK shift, and go to state 1698
COLUMN shift, and go to state 1742
CONSTRAINT shift, and go to state 1699
EXCLUSION shift, and go to state 1700
FOREIGN shift, and go to state 1701
PRIMARY shift, and go to state 1702
UNIQUE shift, and go to state 1703

EXCLUSION [reduce using rule 887 (opt_column)]
$default reduce using rule 887 (opt_column)

TableConstraint go to state 1743
ConstraintElem go to state 1705
opt_column go to state 1744

This is the state immediately after scanning "ADD" in an ALTER TABLE
command, and what it's unhappy about is that it has two different things
to do if the next token is EXCLUSION. (The dot in the productions
indicates "where we are", and the square brackets mark the unreachable
action.) If you check the other mentioned states it becomes clear that
the state-1700 path leads to deciding that EXCLUSION begins a
TableConstraint, while rule 887 is the "empty" alternative for
opt_column, and is what would have to be done next if EXCLUSION is a
column name beginning a ColumnDef. So the difficulty is that it can't
be sure whether EXCLUSION is a column name without looking one token
past EXCLUSION, but it has to decide whether to eliminate COLUMN before
it can look ahead past EXCLUSION.

This is a pretty common difficulty with empty-producing productions.
The usual way around it is to eliminate the empty production by making
the calling production a bit more redundant. In this case, we can fix
it by replacing

alter_table_cmd:
ADD_P opt_column columnDef

with two productions

alter_table_cmd:
ADD_P columnDef
| ADD_P COLUMN columnDef

The reason this fixes it is that now the parser does not have to make
a shift-reduce decision while EXCLUSION is the next token: it's just
going to shift all the time, and it only has to reduce once EXCLUSION
is the current token and it can see the next one as lookahead. (In
which case, it will reduce EXCLUSION to ColId and proceed with the
its-a-ColumnDef path, only if the next token isn't "(" or "USING".)

Another way to think about is is that we are forcing bison to split
this one state into two, but I find it easier to understand how to
fix the problem by looking for ways to postpone the reduce decision.

So IOW, you need the attached patch to the patch.

regards, tom lane

Attachment Content-Type Size
fix-conflict.patch text/x-patch 741 bytes

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2009-11-07 02:23:32 Re: operator exclusion constraints
Previous Message Jeff Davis 2009-11-07 01:46:24 Re: operator exclusion constraints