一条 SQL 的查询优化之旅【下】

本文深入探讨Apache Calcite的SQL解析关键原理,包括SQL解析、元数据验证和关系代数转换。详细阐述了Calcite的SQL校验过程、元数据验证的三个验证点,以及关系代数转换流程。同时,介绍了SQL执行计划生成与优化,包括RBO启发式优化、物化视图改写和CBO基于代价的优化。最后,讨论了Calcite的SQL方言转换,强调了RelToSqlConverter和SqlDialect在方言转换中的角色。Apache Calcite在众多开源和商业项目中的广泛应用,证明了其在SQL处理和优化方面的成熟性。
摘要由CSDN通过智能技术生成

上一篇文章我们讲解了 Apache Calcite 架构设计及 SQL 优化器概述,这篇文章我们将接着介绍 Apache Calcite 组件的关键原理。

三、Calcite SQL 解析和元数据验证关键原理解析

3.1 Calcite SQL 解析关键原理

当一条 SQL 语句到达引擎,首先通过的是 SQL 解析器,SQL 解析器将用户输入的 SQL 语句转换为一棵抽象语法树,同时在这个过程里,它还会对SQL进行词法和语法校验,如果输入的 SQL 有词法或语法问题,会在这个阶段收到错误提示。

在 Calcite 中,一棵抽象语法树通常用SqlNode来表示。以下面这条 SQL 为例:

这条SQL在经过 Calcite 解析后,形成的 AST 抽象语法树如下:

图中的每一个节点都是一个 SqlNode,SqlNode作为抽象语法树的顶级抽象,相互关联组成了一颗大的抽象语法树。

Calcite 支持通过两种方式进行 SQL 解析:即基于 Java CC(Java Compiler Compiler)的 SQL 解析以及基于 Anltr 的 SQL 解析。Calcite 默认基于 Java CC 来做 SQL 解析:Calcite 能够基于Parser.jj 文件,使用 Java CC 技术,动态生成 SQL 解析实现类(XXXParserImpl),Calcite 本身内置有一个 Parser.jj 文件,如果我们需要自定义 SQL 语法的时候,我们也可以使用 FMPP 技术,自定义 ftl和 config.fmpp 文件的内容,来控制最终需要生成的Parser.jj 的内容,从而实现自定义 SQL 语法。

config.fmpp 主要定义 SQL 语法中的关键字、外部引入的类(如自定义的 SqlNode)、以及一些 SQL 解析方法定义等等,具体的实现一般会在 ftl 文件中。以 Apahce Flink 项目举例,组成其 SQL 解析器模块的主要文件如下:

3.2 Calcite SQL 校验和关系代数转换流程

3.2.1 Calcite SQL 元数据校验

上文我们提到:SQL 解析后会形成一棵 SqlNode 的抽象语法树,下一步我们需要对这棵树进行元数据验证,以校验SQL的合法性。这里需要注意,经过元数据验证之后的SqlNode,其本质还是一棵SqlNode 树,之后依然需要经过 SqlNode 到RelNode关系代数的转换,才会形成一棵由RelNode组成的关系代数节点树。

在 Calcite 元数据验证阶段,其主要验证三个点:

  • 对 SQL 语句中的 Table Schema 进行校验,如 Table 存不存在,Column 存不存在
  • 对 SQL 语句中函数进行校验,如函数是否存在
  • 针对数据类型的校验,如函数中的参数数据类型和函数定义是否匹配

Calcite 中元数据验证源码的核心方法入口为:SqlValidatorImpl.validate(),SqlValidatorImpl的使用,需要配合SqlOperatorTable,SqlValidatorCatalogReader,RelDataTypeFactory三个类使用。SqlValidatorImpl 的初始化构造器的源码如下:

初始化 SqlValidatorImpl 需要传入三类参数:

  • SqlOperatorTable-生产函数和 SQL Operator 的工厂
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值