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_alias
是any_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".
答案 0 :(得分:0)
该行为是正确的。 LEFT
中包含keyword
规则,而该规则依次在any_name
中使用,table_alias
是table_alias
的有效输入(这称为 keywords-as-标识符问题)。根据语法,您的查询是错误的。表名后面的任何单词都是表别名,无论它通常不是关键字。
一种解决方法是添加一个验证谓词,该谓词将检查以下标记,并且如果当前标记是应按其原始含义使用的规则,则LEFT
规则将失败。通过从keyword
规则中删除LEFT
关键字,可以得到相同的结果。但是,这可能会在您希望将关键字public void acquire()
throws InterruptedException
用作标识符的有效输入的地方产生其他副作用。