Java 查找令牌';使用JSqlParser在SQL查询中的位置
我试图用JSqlParser在SQL查询中查找SQL对象(令牌?)的位置(行就足够了) 例如,在查询中:Java 查找令牌';使用JSqlParser在SQL查询中的位置,java,jsqlparser,Java,Jsqlparser,我试图用JSqlParser在SQL查询中查找SQL对象(令牌?)的位置(行就足够了) 例如,在查询中: SELECT a FROM table WHERE a = 1 AND b = 2 AND c = 3 当看到表达式b=2时,我想知道它在第4行。或者,当查看SelectItem“a”时,我想知道它在第1行 没有在文档中或对象本身中看到任何关于其位置的信息。 如果这在目前还不可能实现,请您提出一个好的方法,让我自己添加此功能(性能方面最简单、最快速)。如果没有经过修
SELECT a
FROM table
WHERE a = 1 AND
b = 2 AND
c = 3
当看到表达式b=2时,我想知道它在第4行。或者,当查看SelectItem“a”时,我想知道它在第1行
没有在文档中或对象本身中看到任何关于其位置的信息。
如果这在目前还不可能实现,请您提出一个好的方法,让我自己添加此功能(性能方面最简单、最快速)。如果没有经过修补的JSqlParser版本,您就不能。目前,JSqlParser V1.2-SNAPSHOT确实为您提供了一些特定解析令牌的AST节点信息,但不是所有令牌的AST节点信息。使用以下代码截取:
public static void main(String[] args) throws JSQLParserException {
String sql = "SELECT a\n"
+ "FROM table\n"
+ "WHERE a = 1 AND\n"
+ " b = 2 AND\n"
+ " c = 3";
SimpleNode node = (SimpleNode) CCJSqlParserUtil.parseAST(sql);
node.jjtAccept(new CCJSqlParserDefaultVisitor() {
@Override
public Object visit(SimpleNode node, Object data) {
System.out.println(node.toString() + " firstToken=" + node.jjtGetFirstToken().image
+ " line=" + node.jjtGetFirstToken().beginLine);
return super.visit(node, data);
}
}, null);
}
您可以获取有关所有保存的AST节点的信息。通过探索SimpleNode的接口,您还可以了解令牌在源sql字符串中的绝对位置和范围
这个“限制”来自JSqlParsers特性驱动的开发和对生成所有AST节点的巨大性能影响。此外,一些AST节点与JSQlParsers链接,解析对象如列、表等。这不是使用JavaCC自动完成的,而是必须在语法定义内完成
首先,我提到了一个经过修补的JSqlParser。通过修改pom.xml和
<nodeDefaultVoid>true</nodeDefaultVoid>
true
至假。然后为所有产品生成AST节点。但你会看到,它会导致一棵大树,即使是你的简单陈述
如果您需要一些特定产品(如EqualTo对象)的此信息,可以通过JSqlParser(github)的功能请求集成此信息
为什么是这两种树?
JSqlParser中的解析树和抽象语法树之间存在差异。对于从ASTNodeAccessImpl扩展而来的对象,这两者之间存在链接。交付的解析树对象是sql解析部分的一种更实用的方法。例如,您可以将表对象设置为列对象,以引用此表中的列。使用AST方法将导致构造更多节点来构造点、标识符等
AST节点具有您需要的信息,即令牌在原始sql文本中的确切位置。如果查看函数对象,可以使用方法getASTNode获取相应的AST节点,以获取sql中的确切位置。但正如我所写的,这只针对少数解析树对象实现。如果您需要特定的节点来获取此信息,我很乐意为此扩展JSqlParser,但请记住,获取所有这些节点会对性能和内存产生巨大影响。感谢您提供的信息。这是一个完全不同的位置对象树?在我的用例中,这实际上没有多大意义,因为我的目标是跟踪已解析语句中的对象(使用JSqlParser的常规对象)并获取它们的位置。例如,如果我在树中找到一个函数名Foo,我还想得到它在原始查询中的位置。你能给我指出正确的方向吗?因为我不想为了得到位置而解析一个全新的节点树(我也不理解对象和节点树之间的关系)。谢谢你提供的信息。您提到,此功能目前仅针对少数解析树对象实现。有没有简单的方法可以为任何对象添加此功能?我需要它用于许多类型(例如:函数、表、列、InExpression、EqualTo、ExistsExpression、LikeExpression、StringValue等)。我知道这可能会导致性能下降,但如果我可以配置需要定位信息的类型,那就最好了。我很高兴知道一些关于如何实现它的指导,即使是我自己,因为它对我来说非常重要。首先,JSqlParser对象类必须从ASTNodeAccessImpl进行扩展,其次必须使用linkAST在语法中链接它,就像在函数生成中一样。谢谢!我试着看看当前的实现——如何在Maven中获得v1.2快照?另外,我应该在哪里添加nodeDefaultVoid配置?你能举个例子吗?只有你自己构建jsqlparser,你才能改变这个。实际的主分支头是1.2-Snapshot。查看pom.xml。可以在sonatype maven repo中引用jar。