Calcite RelTrait

Calcite - RelTrait

/**
 * RelTrait represents the manifestation of a relational expression trait within
 * a trait definition. For example, a {@code CallingConvention.JAVA} is a trait
 * of the {@link ConventionTraitDef} trait definition.
 */
public interface RelTrait {
  /**
   * Returns the RelTraitDef that defines this RelTrait.
   */
  RelTraitDef getTraitDef();
}

RelTrait 代表了在一个特定的 trait definition 中的关系表达式特征的表现形式。
比如说,CallingConvention.JAVA 是在 ConventionTraitDef 这个 trait definition 中的一个特征。

简单来讲,RelTrait 表示 RelNode 的物理属性。

RelTraitDef

/**
* RelTraitDef represents a class of RelTraits
* @param <T> Trait that this trait definition is based upon
*/
public abstract class RelTraitDef<T extends RelTrait> {

}

官方文档:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nMnTqHL5-1588851654779)(assets/markdown-img-paste-20191217125240616.png)]

RelTraitDef 代表了一类(组)RelTraits。

RelTraitDef的实现可以是单例的,条件如下:

  1. 如果所有可能的相关 RelTraits 是有限的和固定的。(比如,这个 RelTraitDef 所有的 RelTraits 在编译时都是已知的)例如:CallingConvention (调用规约)特征满足这个要求,因为 CallingConvention 实际上是一个枚举。以下是调用规约特征的实现:

  2. canConvert(RelOptPlanner, RelTrait, RelTrait)convert(RelOptPlanner, RelNode, RelTrait, boolean) 不需要 planner 实例相关的信息

    或者 RelTraitDef 在内部管理独立的转换数据集。参见 ConventionTraitDef for an example。

如果不满足以上两个条件,则必须构造一个 RelTraitDef 的新实例,并将其注册到每个实例化的 new planner 中。

RelTraitDef 三种类型

RelTraitDef 代表了 RelTrait 的类型,实际还是 RelNode 的属性。RelTraitDef 主要可以分为3种, ConventionTraitDef, RelCollationTraitDef, RelDistributionTraitDef.
RelTraitDef 中重要的转换函数,convert() 把给定的 RelNode 转换为给定的特征。

  /**
   * Converts the given RelNode to the given RelTrait.
   *
   * @param planner                     the planner requesting the conversion
   * @param rel                         RelNode to convert
   * @param toTrait                     RelTrait to convert to
   * @param allowInfiniteCostConverters flag indicating whether infinite cost
   *                                    converters are allowed
   * @return a converted RelNode or null if conversion is not possible
   */
  public abstract RelNode convert(
      RelOptPlanner planner,
      RelNode rel,
      T toTrait,
      boolean allowInfiniteCostConverters);

  /**
   * Tests whether the given RelTrait can be converted to another RelTrait.
   *
   * @param planner   the planner requesting the conversion test
   * @param fromTrait the RelTrait to convert from
   * @param toTrait   the RelTrait to convert to
   * @return true if fromTrait can be converted to toTrait
   */
  public abstract boolean canConvert(
      RelOptPlanner planner,
      T fromTrait,
      T toTrait);

RelCollationTraitDef

Definition of the ordering trait. 排序特征。

RelDistributionTraitDef

Definition of the distribution trait. 分布特征

ConventionTraitDef

官方文档:Definition of the the convention trait. A new set of conversion information is created for each planner that registers at least one ConverterRule instance.

Conversion data is held in a LoadingCache with weak keys so that the JVM’s garbage collector may reclaim the conversion data after the planner itself has been garbage collected. The conversion information consists of a graph of conversions (from one calling convention to another) and a map of graph arcs to ConverterRules.

Definition of the convention trait. 转换特征。

Calling conventions

官方文档:A calling convention is a protocol used by a particular data engine. For example, the Cassandra engine has a collection of relational operators, CassandraProject, CassandraFilter and so forth, and these operators can be connected to each other without the data having to be converted from one format to another.

Calling Convention 指的是一个特定数据引擎的协议。比如,Cassandra 引擎有 CassandraProjectCassandraFilter 等关系运算符,这些运算符可以相互连接而不必把数据从一种形式转化为另一种形式。

If data needs to be converted from one calling convention to another, Calcite uses a special sub-class of relational expression called a converter (see class Converter). But of course converting data has a runtime cost.

如果需要从一个 convention 转化到另一个,那么 Calcite 使用 RelNode 的一个特殊子类:converter.

A calling convention is a class that implements interface Convention, an auxiliary interface (for instance interface CassandraRel), and a set of sub-classes of class RelNode that implement that interface for the core relational operators (Project, Filter, Aggregate, and so forth).

一个 Calling Convention 是一个类,该类实现了 Convention 接口(这是一个辅助接口,比如 CassandraRel),和 RelNode 的一组子类,实现了核心关系操作符(Project, Filter, Aggregate等)。

Convention
// Calling convention trait.
public interface Convention extends RelTrait{
    /**
   * Convention that for a relational expression that does not support any
   * convention. It is not implementable, and has to be transformed to
   * something else in order to be implemented.
   * Convention None 表示关系表达式不支持任何 convention。
   * Relational expressions generally start off in this form.
   * 关系表达式通常以这种形式开始。
   * Such expressions always have infinite cost.
   * 这种表达式总有无限的 cost。
   */
  Convention NONE = new Impl("NONE", RelNode.class);
}

Convention 代表关系表达式在特定数据引擎的特征,比如说 EnumerableConvention,代表 Enumerable 特征。CassandraFilterCassandraProject等关系表达式都满足在 CassandraRel 中定义的 CASSANDRA Convention.

NONE规约,表示表达式不支持任何 Convention。

Convention中还有两个重要的方法为canConvertConvention(Convention toConvention)useAbstractConvertersForConversion(RelTraitSet fromTraits,RelTraitSet toTraits)

  /**
   * Returns whether we should convert from this convention to
   * {@code toConvention}. Used by {@link ConventionTraitDef}.
   * note: 返回是否我们应该从现在的 Convention 转化为参数给定的 toConvention.
   * @param toConvention Desired convention to convert to
   * @return Whether we should convert from this convention to toConvention
   */
  boolean canConvertConvention(Convention toConvention);

  /**
   * Returns whether we should convert from this trait set to the other trait set.
   * note: 返回是否我们应该从现在的 trait set 转化为
   * <p>The convention decides whether it wants to handle other trait
   * conversions, e.g. collation, distribution, etc.  For a given convention, we
   * will only add abstract converters to handle the trait (convention,
   * collation, distribution, etc.) conversions if this function returns true.
   * note:这个规约决定了是否它应该处理其他特征转换,比如排序、分布。
   * note:对于一个给定的规约,如果该函数返回true,我们将只添加抽象转换器来处理特征(规约、排序、分布等)转换。
   * @param fromTraits Traits of the RelNode that we are converting from
   * @param toTraits Target traits
   * @return Whether we should add converters
   */
  boolean useAbstractConvertersForConversion(RelTraitSet fromTraits,
      RelTraitSet toTraits);

ConverterRule

官方文档:Abstract base class for a rule which converts from one calling convention to another without changing semantics.

在不改变语义的前提下从一个 calling convention 转换到另一个 calling convention 的 rule.

RelOptRule 与 ConverterRule 的区别

ConverterRule is a subclass of the RelOptRule class. Both of these are rules used by the planner to transform relational algebra expressions. A ConverterRule does what the Javadoc you cited states, it converts between calling conventions. This is used for example to allow logical expressions to be actually executed by assigning a particular calling convention, which indicates what system will actually execute the query.

ConverterRuleRelOptRule 的子类。两种 rule 都是 planner 用来转换关系表达式的。ConverterRule 用于在 calling conventions 之间转换。例如,它允许通过指定一个特定的 calling convention 来实际执行逻辑表达式,其表明了实际执行查询的系统。

Rules can do many other things besides convert conventions. For example, a rule may decide to exchange the order of Filter and a Project nodes. Really all a rule does is match a subtree of a relational algebra expression and replace it with a different subtree.

除了转换规约之外,rules 还可以做许多其他的事情。例如,rule 可能决定交换 FilterProject 节点的顺序。实际上,rule 所做的就是匹配关系代数表达式的子树,并将其替换为不同的子树。

### Apache Calcite 介绍 Apache Calcite 是一个动态数据管理框架,专注于查询处理和优化。它提供了一套丰富的工具集用于构建基于 SQL 和其他声明性语言的数据处理应用。Calcite 不仅支持标准的 SQL 查询语法,还允许开发者定义自定义函数、聚合操作符以及其他扩展特性[^1]。 #### 功能特点 - **SQL 解析**:能够将 SQL 文本转换成抽象语法树(AST),便于后续处理。 - **查询重写与优化**:内置多种策略来进行逻辑计划改写及物理执行路径的选择。 - **多源联邦查询**:可以跨多个异构数据库系统执行联合查询。 - **灵活的数据模型**:除了关系型表格外,也兼容 JSON、Avro 等非结构化格式。 - **插件机制**:易于集成第三方存储引擎或计算平台作为新的适配层。 ### 使用场景 #### 场景一:SQL 解析服务 当应用程序需要接收并解释用户的输入命令时,可以通过调用 Calcite 提供的 API 来完成这一任务而无需依赖具体的 RDBMS 实现细节。例如,在开发 BI 工具的过程中,为了实现即席查询功能,则可利用其强大的解析能力快速响应前端请求[^2]。 ```java // 创建 SqlParser 对象实例 SqlParser parser = SqlParser.create("SELECT * FROM sales WHERE amount > 100"); ParseResult result = parser.parseQuery(); ``` #### 场景二:独立查询优化组件 对于那些已经具备完善的数据访问接口的应用程序来说,如果希望进一步提升性能表现而不改变现有架构设计的话,那么引入 Calcite 的查询优化模块不失为一种理想方案。此时并不涉及实际 I/O 操作,因此也不必加载任何特定于某个 DBMS 的 JDBC 驱动程序[^3]。 ```sql -- 定义虚拟模式下的视图定义语句 CREATE VIEW v_orders AS SELECT o.order_id, c.customer_name FROM orders o JOIN customers c ON o.cust_id = c.id; ``` #### 场景三:分布式计算环境中的元数据管理层 像 Spark 或 Flink 这样的大数据处理框架往往面临着来自不同源头海量信息汇聚的需求,这时借助 Calcite 可以为用户提供统一视角去管理和操纵这些资源。具体做法是在上层封装一层轻量级的服务端点负责接受客户端提交的任务描述文件,并据此生成相应的中间表示形式传递给底层调度器安排作业执行流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值