Go语言 如何支持“FULL JOIN”子句

bsxbgnwa  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(110)

我正在尝试在TiDB解析器(https://github.com/pingcap/tidb/tree/master/parser)中添加“FULL JOIN”支持。我对parser. y做了两个不同的修改。尝试一:我修改了“JoinTable”的定义如下:

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}
    }

尝试二:我将“JoinType”的定义改为:

JoinType:
    "LEFT"
    {
        $$ = ast.LeftJoin
    }
|   "RIGHT"
    {
        $$ = ast.RightJoin
    }
|   "FULL"
    {
        $$ = ast.FullJoin
    }

在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")
    }
...
}

在这两种情况下我都得到了“冲突:2 shift/reduce”in make.In y.output我发现了以下行:

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

现在我明白了问题出在“FULL”上,下一步可能是“shift,后藤state 237”,或者“reduce using rule 1478”,但我不知道如何解决这个问题。我尝试在优先级列表的末尾添加一个新的“% precision full”,并重复使用“%prec tableRefPriority”,但错误仍然存在。任何帮助将不胜感激!

k4ymrczo

k4ymrczo1#

我是TiDB的维护者之一。我已经试过你的第二种方法,它在我这边起作用了。我没有遇到任何shift/reduce错误。此外,我成功地运行了新构建的TiDB,并测试了解析完整的连接语句,这也是成功的。你是否使用了'make parser'来构建parser.go文件?
顺便说一下,由于MySQL不支持Full Join,如果你想在TiDB中实现它,请先在github.com/pingcap/tidb上创建一个问题,这将允许我们讨论是否接受此功能。

相关问题