sqlite3.g4语法无法正确处理左连接

时间:2018-07-06 23:31:17

标签: antlr4

github sqlite3语法github.com/antlr/grammars-v4/blob/master/sqlite/SQLite.g4出现左联接问题。

对于此sql

select * from t1 left join t2 on t1.owner = t2.email

单词“ left”被解析为table_alias。事情从那里迅速下坡

我想我可以通过说table_aliasany_name来解决它,除了K_LEFT,K_RIGHT,K_INNER之外,但我不知道该如何用语法来表达

或者也许有更好的方法来解决这个问题

更新。只是为了澄清sqlite的行为。 (不是在谈论antlr,而是在谈论sqlite理解什么)

这个

select username from user left join device on device.owner = user.id limit 2

有效。

select username from user alias join device on device.owner = user.id limit 2

未能说出user.id列不存在。

很明显,单词“ left”被识别为关键字,而不是表别名。

select username from user alias join device on device.owner = alias.id limit 2

有效,并进行内部联接

select username from user alias left join device on device.owner = user.id limit 2

起作用并进行左联接

@Mike Lischke的进一步更新

select username from user left where device.owner = left.id limit 2

失败。 "Query has failed: near "where": syntax error".

1 个答案:

答案 0 :(得分:0)

该行为是正确的。 LEFT中包含keyword规则,而该规则依次在any_name中使用,table_aliastable_alias的有效输入(这称为 keywords-as-标识符问题)。根据语法,您的查询是错误的。表名后面的任何单词都是表别名,无论它通常不是关键字。

一种解决方法是添加一个验证谓词,该谓词将检查以下标记,并且如果当前标记是应按其原始含义使用的规则,则LEFT规则将失败。通过从keyword规则中删除LEFT关键字,可以得到相同的结果。但是,这可能会在您希望将关键字public void acquire() throws InterruptedException 用作标识符的有效输入的地方产生其他副作用。