github sqlite3语法github.com/antlr/grammars-v4/blob/master/sqlite/SQLite.g4存在左连接问题.
对于这个sql
select * from t1 left join t2 on t1.owner = t2.email
Run Code Online (Sandbox Code Playgroud)
"left"这个词被解析为table_alias.事情从那里迅速走下坡路
我想我可以通过某种方式说,解决这个问题table_alias
是any_name
除K_LEFT,K_RIGHT,K_INNER但我不知道该如何表达,在一个语法
或者也许有更好的方法来解决这个问题
UPDATE.只是为了澄清sqlite的行为.(不是谈论antlr,谈论sqlite理解的内容)
这个
select username from user left join device on device.owner = user.id limit 2
Run Code Online (Sandbox Code Playgroud)
作品.
这个
select username from user alias join device on device.owner = user.id limit 2
Run Code Online (Sandbox Code Playgroud)
没有说列user.id不存在.
显然,"左"这个词被识别为关键字而不是表别名.
select username from user alias join device on device.owner = alias.id limit 2
Run Code Online (Sandbox Code Playgroud)
工作,并进行内部联接
select username from user alias left join device on device.owner = user.id limit 2
Run Code Online (Sandbox Code Playgroud)
工作并做左连接
@Mike Lischke的进一步更新
select username from user left where device.owner = left.id limit 2
Run Code Online (Sandbox Code Playgroud)
失败. "Query has failed: near "where": syntax error".
行为是正确的。LEFT
包含在keyword
规则中,该规则又用于any_name
,这是 的有效输入table_alias
(这称为关键字作为标识符问题)。根据语法,您的查询是错误的。表名后面的任何单词都是表别名,无论它通常是否是关键字。
解决方法可能是添加一个验证谓词,该谓词检查以下标记,table_alias
如果当前标记应以其原始含义使用,则该规则将失败。LEFT
通过从规则中删除关键字可以获得相同的结果keyword
。但是,在您希望关键字LEFT
成为标识符的有效输入的地方,这可能会产生其他副作用。