Calcite初识
一言以蔽之
- As a database without a storage layer
- Calcite doesn’t know about any file formats
基本使用步骤
- 在一个model文件中定义schema
- Schema Factory类创建该schema
- 该schema创建tables,每个table都知道自己该如何扫描数据
- Calcite解析查询语句(SQL)并计划如何查询这些tables
- Calcite提醒表去读取数据, 以完成查询语句(SQL)的执行
Scnema模版
官方给的读取CSV示例的Schema模版如下:
{
version: '1.0',
defaultSchema: 'SALES',
schemas: [
{
name: 'SALES',
type: 'custom',
factory: 'org.apache.calcite.adapter.csv.CsvSchemaFactory',
operand: {
directory: 'target/test-classes/sales'
}
}
]
}
该模版给出了schema文件的基本元素
简单的运行机制分析
- 通过实现SchemaFactory接口的插件类, 执行create方法, 完成schema的实例化
- 具体的插件类在schema文件中的
factory
字段指定了 - create方法中的参数通过schema文件中的
operand
字段指定 - create方法会实例化一个具体的实现了Schema接口的Schema类(用户自己的Schema类)
- 具体的插件类在schema文件中的
- 一个Schema类的作用在于管理和自己相关的表和函数
- 用户自定义的Schema类Override了
Map<String, Table> getTableMap()
方法
- 用户自定义的Schema类Override了
- Schema类产生的表均实现了Calcite的Table接口
- 官方提供的几种实现该Table接口的抽象类,用户可以继承
- 用户的每一种Table类均可以给出自己的数据读写方法
视图和用户表
- schema可以自动产出表,在用户自己的Schema类中给出了创建表的方法
- 用户也可以在schema文件中通过
tables
字段创建扩展类型的表- Calcite支持视图和用户表,只需在schema文件中注明
view
或custom
用户表
custom
类型的用户表, 表的实现均由用户自己完成(高度可定制化)- 用户表的具体类由用户在schema文件中的
tables.factory
字段中指定的具体TableFactory类的create()
方法进行实例化 - 用户具体的TableFactory类实现了
TableFactory
接口 - TableFactory类只会通过用户定义的
tables
字段启动
添加规则进行查询优化
- Calcite supports query optimization by adding planner rules.
- Table scans are the leaves of a query operator tree. The usual implementation is
EnumerableTableScan
- 用户自己实现的
TableScan类
中会注册用户自行添加的规则Rule类
- 用户自己实现的
TableScanRule类
(需要继承RelOptRule抽象类
)负责具体的实现