I'm trying to add "FULL JOIN" support in TiDB parser(https://github.com/pingcap/tidb/tree/master/parser). I tried two different modifications to parser.y. In attempt one: I changed the definition of "JoinTable" as follows:
JoinTable:
| TableRef "FULL" "JOIN" TableRef "ON" Expression
{
on := &ast.OnCondition{Expr: $6}
$$ = &ast.Join{Left: $1.(ast.ResultSetNode), Right: $4.(ast.ResultSetNode), Tp: ast.FullJoin, On: on}
}
and in attempt two: I changed the definition of "JoinType" to:
JoinType:
"LEFT"
{
$$ = ast.LeftJoin
}
| "RIGHT"
{
$$ = ast.RightJoin
}
| "FULL"
{
$$ = ast.FullJoin
}
and in dml.go:
// JoinType is join type, including cross/left/right/full.
type JoinType int
const (
// CrossJoin is cross join type.
CrossJoin JoinType = iota + 1
// LeftJoin is left Join type.
LeftJoin
// RightJoin is right Join type.
RightJoin
// FullJoin is full Join type.
FullJoin
)
// Restore implements Node interface.
func (n *Join) Restore(ctx *format.RestoreCtx) error {
...
switch n.Tp {
case LeftJoin:
ctx.WriteKeyWord(" LEFT")
case RightJoin:
ctx.WriteKeyWord(" RIGHT")
case FullJoin:
ctx.WriteKeyWord(" FULL")
}
...
}
and in both cases I got "conflicts: 2 shift/reduce" in make.In y.output I found the following lines:
state 1810 // update '(' selectKwd '*' ')'
1474 TableFactor: '(' SetOprStmt1 ')' . TableAsNameOpt // assoc %precedence, prec 56
1478 TableAsNameOpt: . [$end, ')', ',', ';', '}', cross, except, fetch, forKwd, full, group, having, inner, intersect, into, join, left, limit, lock, natural, on, order, right, set, straightJoin, union, using, where, window, with]
$end reduce using rule 1478 (TableAsNameOpt)
')' reduce using rule 1478 (TableAsNameOpt)
',' reduce using rule 1478 (TableAsNameOpt)
';' reduce using rule 1478 (TableAsNameOpt)
'}' reduce using rule 1478 (TableAsNameOpt)
account shift, and goto state 387
...
format shift, and goto state 236
full shift, and goto state 237
function shift, and goto state 331
...
jobs shift, and goto state 521
join reduce using rule 1478 (TableAsNameOpt)
jsonArrayagg shift, and goto state 603
...
Identifier goto state 1813
NotKeywordToken goto state 180
TableAsName goto state 1812
TableAsNameOpt goto state 1811
TiDBKeyword goto state 181
UnReservedKeyword goto state 179
conflict on full, shift, and goto state 237, reduce using rule 1478 // full: assoc %left, prec 33
Now I understand the problem is with "FULL", the next step could be both "shift, and goto state 237", or "reduce using rule 1478", but I'v got no clue how to solve this. I tried to add a new "%precedence full" to the end of precedence list and reusing "%prec tableRefPriority", but the error remains. Any help would be appreciated!
I am one of the maintainers for TiDB. I have tried your second method and it worked on my end. I did not encounter any shift/reduce errors. Additionally, I successfully ran the newly built TiDB and tested parsing a full join statement, which was successful as well. Did you use 'make parser' to build the parser.go file?
By the way, since MySQL does not support Full Join, if you want to implement it in TiDB, could you please create an issue on github.com/pingcap/tidb first? This will allow us to discuss whether this feature would be accepted or not.