如何实现一个SQL解析器( 六 )


如何实现一个SQL解析器

文章插图
上图就是比较典型的适配器用法,比如通过Kafka的适配器就能直接在应用层通过SQL,而底层自动转换成Java和Kafka进行数据交互(后面部分有个案例操作) 。
4.2.2 Calcite实现KSQL查询Kafk参考了EFAK(原Kafka Eagle开源项目)的SQL实现,来查询Kafka中Topic里面的数据 。
1.常规SQL查询
SQL查询
select * from video_search_query where partition in (0) limit 10
如何实现一个SQL解析器

文章插图
预览截图:
如何实现一个SQL解析器

文章插图
2.UDF查询
SQL查询
如何实现一个SQL解析器

文章插图
select JSON(msg,'query') as query,JSON(msg,'pv') as pv from video_search_query where `partition` in (0) limit 10预览截图:
如何实现一个SQL解析器

文章插图
4.3 ANTLR4 和 Calcite SQL解析对比4.3.1 ANTLR4解析SQLANTLR4解析SQL的主要流程包含:定义词法和语法文件、编写SQL解析逻辑类、主服务调用SQL逻辑类 。
1.定义词法和语法文件
可参考官网提供的开源地址:详情
2.编写SQL解析逻辑类
这里,我们编写一个实现解析SQL表名的类,具体实现代码如下所示:
解析表名
如何实现一个SQL解析器

文章插图
public class TableListener extends antlr4.sql.MySqlParserBaseListener {private String tableName = null;public void enterQueryCreateTable(antlr4.sql.MySqlParser.QueryCreateTableContext ctx) {List<MySqlParser.TableNameContext> tableSourceContexts = ctx.getRuleContexts(antlr4.sql.MySqlParser.TableNameContext.class);for (antlr4.sql.MySqlParser.TableNameContext tableSource : tableSourceContexts) {// 获取表名tableName = tableSource.getText();}}public String getTableName() {return tableName;}}3.主服务调用SQL逻辑类
对实现SQL解析的逻辑类进行调用,具体代码如下所示:
主服务
如何实现一个SQL解析器

文章插图
public class AntlrClient {public static void main(String[] args) {// antlr4 格式化SQLantlr4.sql.MySqlLexer lexer = new antlr4.sql.MySqlLexer(CharStreams.fromString("create table table2 select tid from table1;"));antlr4.sql.MySqlParser parser = new antlr4.sql.MySqlParser(new CommonTokenStream(lexer));// 定义TableListenerTableListener listener = new TableListener();ParseTreeWalker.DEFAULT.walk(listener, parser.sqlStatements());// 获取表名String tableName= listener.getTableName();// 输出表名System.out.println(tableName);}} 4.3.2 Calcite解析SQLCalcite解析SQL的流程相比较ANTLR是比较简单的,开发中无需关注词法和语法文件的定义和编写,只需关注具体的业务逻辑实现 。比如实现一个SQL的COUNT操作,Calcite实现步骤如下所示 。
1.pom依赖
Calcite依赖JAR
如何实现一个SQL解析器

文章插图
如何实现一个SQL解析器

文章插图
<dependencies><!-- 这里对Calcite适配依赖进行封装,引入下列包即可 --><dependency><groupId>org.smartloli</groupId><artifactId>jsql-client</artifactId><version>1.0.0</version></dependency></dependencies> 

经验总结扩展阅读