Apache Calcite原理解析(3)--解析层

1、Calcite的解析过程

1.1、解析过程

用户的操作请求经过服务层的接收和封装被传递给calcite-core模块,对SQL的处理第一层是解析层。在这个过程中,初始的SQL字符串会被转化为Calcite内部的语法解析节点,为进一步的语法校验和优化做准备。

语法解析过程主要可以分为3个阶段:
1、首先字符串处理器会将源语句中的字符串转换成字符流;
2、然后词法分析器会对字符流中的一些词法进行匹配,形成词组(Token)流;
3、最后由语法分析器将这些词组流进行语义逻辑的理解,转变为最终的抽象语法树
在这里插入图片描述
然后在解析的过程中,还会注册两个监听器,一个是负责检查语法是否存在错误的异常监听器;另外一个是负责维护词法和语法匹配逻辑的表格管理器

1.2、Calcite中的解析体系

语法解析的最终结果是从SQL字符串得到一个抽象语法树,在Calcite中使用SQLNode负责封装抽象语法树中各个节点的语义信息。

在Calcite中SqlNode的实现类有40多个,每个类都代表一个节点到源码结构的映射,其大致可以分为3类,即SqlLiteralSqlIdentifierSqlCall
在这里插入图片描述

SqlLiteral 主要是封装输入的常量,也称为字面量;
SqlIdentifier 主要是封装输入的标识符,比如表名称,字段名称;
SqlCall 主要是SQL中的每个操作,比如Select对应SqlSelect,插入对应SqlInsert。

比如select idfrom t where id > 1 解析后的SQLNode树为:
在这里插入图片描述

2、JavaCC实现解析逻辑

JavaCC 代码生成器,它的作用就是生成在语法解析过程中的词法分析器和语法分析器。

通过模板文件(例如.jj文件、.jjt文件以及.jtb文件)来生成Java程序(词法和语法解析器),Calcite利用这些Java程序来完成语法解析的工作。

然后对于语法的扩展都是通过config.fmpp文件配置。

3、Antlr4实现解析逻辑

Antlr4是通过.g4文件进行语法的扩展。

4、JavaCC扩展自定义语法

4.1、使用JavaCC解析器

Calcite中,JavaCC 的依赖已经被封装到 calcite-core 模块当中,如果使用 Maven 作为依赖管理工具,只需要添加对应的calcite-core模块坐标即可。

<dependency>
    <groupId>org.apache.calcite</groupId>
    <artifactId>calcite-core</artifactId>
    <version>1.26.0</version>
</dependency>

在代码中,可以直接使用 Calcite 的 SqlParser 接口调用对应的语法解析流程,对相关的 SQL 语句进行解析。

// SQL语句
String sql = "select * from t_user where id = 1";
// 解析配置
SqlParser.Config mysqlConfig = SqlParser.config().withLex(Lex.MYSQL);
// 创建解析器
SqlParser parser = SqlParser.create(sql, mysqlConfig);
// 解析SQL语句
SqlNode sqlNode = parser.parseQuery();
System.out.println(sqlNode.toString());

4.2、自定义语法

Load操作时将数据从一种数据源导入另一种数据源中,Load操作采用的语法模板如下。
修改config.fmpp文件扩充语法支持:

LOAD sourceType:obj TO targetType:obj 
(fromCol toCol (,fromCol toCol)*) 
[SEPARATOR '\t']

如下展示了 Calcite 通过模板引擎添加语法逻辑相关的文件结构,其源码将 Parser.jj 这个语法文件定义为模板,将 includes 目录下的.ftl文件作为扩展文件,最后统一通过config.fmpp来配置。
在这里插入图片描述

4.3、汇总

总的来说,Calcite扩展自定义语法,可以分为三步:
1、编写新的 JavaCC 语法文件:不需要修改Parser.jj文件,只需要修改includes目录下的.ftl文件,对于前文提出的Load操作,只需要在parserImpls.ftl文件里增加Load对应的语法。
2、修改config.fmpp文件,配置自定义语法: 需要将 Calcite 源码中的 config.fmpp 文件复制到项目的 src/main/codegen 目录下,然后修改里面的内容,来声明扩展的语法部分。
3、编译模板文件和语法文件: 在这个过程当中,需要将模板Parser.jj文件编译成真正的Parser.jj文件,然后根据Parser.jj文件生成语法解析代码。(需要maven插件来完成)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值