dt-sql-parser icon indicating copy to clipboard operation
dt-sql-parser copied to clipboard

[Bug]: getAllEntities的isContainCaret判断异常

Open ouzhou opened this issue 1 year ago • 2 comments

Version

4.0.0

Which SQL?

MySQL

SQL content

SELECT * FROM tb where    ;

JavaScript/TypeScript code

import { FlinkSQL } from "dt-sql-parser";
const flink = new FlinkSQL();
const sql = "SELECT * FROM tb where    ;";
console.log(sql.length);// 27
const pos = { lineNumber: 1, column: 25 }; // tb 的后面
const entities = flink.getAllEntities(sql, pos);

console.log(entities);// [0].belongStmt.isContainCaret 为false

What happened?

sql语句长27个字符,当光标在第25个字符,也就是where后面2个空格的位置 期望打印的isContainCaret为true

Relevant log output

No response

ouzhou avatar Apr 08 '24 07:04 ouzhou

想使用光标位置获取当语句内出现的表名,去做字段推荐。 经过测试发现除了where其他的比如order by这样的后面都无法判断在同一个语句内

ouzhou avatar Apr 08 '24 07:04 ouzhou

猜测是因为在语法规则src/grammar/mysql/MySqlParser.g4里,whereClause必须带后面的表达式才能被作为一个token。单纯的where不被作为一个token:

image

所以实际上解析时上下文丢弃了where之后的内容,又因为光标位也在where之后,所以根据iisContainCaret的逻辑:

image

不满足结束tokenIndex大于光标位置,所以就返回false了。

这个可以暂时通过在where后面添加一个占位符来workaround,其他有类似情况的语句同。

SELECT * FROM tb WHERE CARET;

彻底解决估计还得看官方如何处理这块的语法。

Kijin-Seija avatar May 28 '24 11:05 Kijin-Seija