calcite是一个动态数据管理框架,它提供了SQL解析与校验,SQL优化,jdbc接口等能力,并且能够支持对不同数据源的适配以及对SQL语法的扩展等,目前被广泛用于Spark, Flink等大数据引擎中。
caltite文档
https://calcite.apache.org/docs/
基础对象和接口
Calcite是一个动态数据管理框架,它提供了sql解析以及jdbc接口,我们可以使用calcite做sql解析或者利用calcite适配器实现通过sql访问任意类型的存储
calcite中的关键接口介绍:
- Table接口:对某种类型的表的抽象,比如calcite内置的JdbcTable表示关系型数据库中的表
- QueryableTable接口:表示可查询的表,表示可以在这类表上执行select语句
- FilterableTable接口:可过滤的表,该接口摘借一个scan方法,calcite实现了对sql中的where条件的过滤,对于一些存储的实现,如果将所有数据查询出来后再过滤往往是行不通的,通过实现此接口,将过滤条件转换成存储的过滤api,先在查询时通过数据源做过滤
- ModifiableTable接口:表示 可修改的表,如果想要对表实现insert, update, delete,则需要实现此接口
- RelNode接口:关系表达式,SQL解析后的对象由关系表达式组成,是一个表达式树
- RelOptRule抽象类:calcite在做SQL优化时使用的转换表达式的规则,比如将RelNode转换成存储系统的查询api的调用
- Schema接口:对表的命名空间的抽象,对应于mysql中的database,一个表必须属于一个schema
实现适配器
实现适配器需要做两件事:
定义schema并实现Table,表示某种类型的表
实现SQL到查询/更新的转换
如果只需要支持查询,则可以实现QueryableTable,如果需要支持通过数据源做条件过滤,则可实现FilterableTable接口
如果需要支持update/insert/delete语句,则需要实现ModifiableTable接口
自定义adapter通过SQL调用http接口
代码地址:https://github.com/gaohanghbut/yugo
首先实现Table:
ObjectTable是一个从AbstractQueryableTable继承的抽象类,其中封装了对字段类型的处理,代码如下:
HttpTable是一个FilterableTable,其scan方法提供了对查询的实现,其逻辑非常简单,拿到可以用于下沉到数据源的过滤参数,并通过过滤参数调用invoker获取scan的结果,calcite会基于此结果对数据再次做过滤,执行不能下沉到数据源的过滤条件得到最终的结果。invoker对象是一个Function,用于提供select语义的支持,通过构造器传入。
接下来定义Schema,可以从AbstractSchema继承:
接下来实现一个工厂,用于创建HttpApiSchema:
tableDefParser的作用是解析operand这个map中的kv,并生成HttpTable对象,而operand则是从json配置中来,json配置中定义schema的基础信息和每个table的基础信息,其中的operand字段的值则是自定义的内容,可自行解析(与上面的tableDefParser的逻辑一致):
最后实现查询逻辑,即invoker那个Function的实现,期核心代码如下:
致此,通过sql的select调用http接口的实现完成,通过jdbc接口使用方式如下:
LogicTableExecutor实现如下: