cockroachdb / cockroach

CockroachDB — the cloud native, distributed SQL database designed for high availability, effortless scale, and control over data placement.
https://www.cockroachlabs.com
Other
29.88k stars 3.77k forks source link

shift/reduce conflict in sql.y #37392

Closed cindyzqt closed 5 years ago

cindyzqt commented 5 years ago

hi guys,

I try to modify the sql.y file as follows:

| table_ref join_type JOIN table_ref
  {
    $$.val = &tree.JoinTableExpr{Join: $2, Left: $1.tblExpr(), Right: $4.tblExpr()}
  }
| table_ref join_type JOIN table_ref join_qual
  {
    $$.val = &tree.JoinTableExpr{Join: $2, Left: $1.tblExpr(), Right: $4.tblExpr(), Cond: $5.joinCond()} 
  }

According to the doc [https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/parser/README.md], I understand there is some madness in SQL that the parser generator doesn't know whether to expect join_qual after table_ref.

But even I add the priority according to the doc as follows, it still reports the same conflict.

| table_ref join_type JOIN table_ref %prec VALUES 
  { 
    $$.val = &tree.JoinTableExpr{Join: $2, Left: $1.tblExpr(), Right: $4.tblExpr()} 
  } 
| table_ref join_type JOIN table_ref join_qual %prec UMINUS
  { 
    $$.val = &tree.JoinTableExpr{Join: $2, Left: $1.tblExpr(), Right: $4.tblExpr(), Cond: $5.joinCond()} 
  }

Anyone could help on this? Appreciate in advance!

andreimatei commented 5 years ago

If there's anyone who can help you, it's @knz

knz commented 5 years ago

@cindyzqt I don't understand what you have modified. I can already see in sql.y:

joined_table:
...
| table_ref join_type opt_join_hint JOIN table_ref join_qual
  {
    $$.val = &tree.JoinTableExpr{JoinType: $2, Left: $1.tblExpr(), Right: $5.tblExpr(), Cond: $6.joinCond(), Hint: $3}
  }
| table_ref JOIN table_ref join_qual
  {
    $$.val = &tree.JoinTableExpr{Left: $1.tblExpr(), Right: $3.tblExpr(), Cond: $4.joinCond()}
  }

The rules are already there, what do you need to add/modify?

cindyzqt commented 5 years ago

@knz

I'm trying to add a rule for the join_type JOIN without the join_qual. See the following:

joined_table:
...
| table_ref join_type JOIN table_ref
  {
    $$.val = &tree.JoinTableExpr{Join: $2, Left: $1.tblExpr(), Right: $4.tblExpr()}
  }
| table_ref join_type JOIN table_ref join_qual
  {
    $$.val = &tree.JoinTableExpr{Join: $2, Left: $1.tblExpr(), Right: $4.tblExpr(), Cond: $5.joinCond()} 
  }

BTW I'm working on 2.1 instead of the master branch.

knz commented 5 years ago

Your proposal is creating an ambiguity for this case:

a join b join c using x

Because you made the join condition optional, this expression can be parsed either as (a join b) join c using x, or a join (b join c using x).

This ambiguity is not resolvable via precedence clauses unfortunately. If you want to keep the rule without join_clause, then you must remove the rule table_ref: joined_table (and keep just table_ref: '(' joined_table ')')

knz commented 5 years ago

I would also recommend that you get a regular textbook on LALR parsers and the oddities of yacc.

ricardocrdb commented 5 years ago

Hello @cindyzqt

Hope you had some luck after the clarification. If you had run into any other issues, please fell free to let us know. I will go ahead and close this issue out.

Cheers, Ricardo