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的实现可以是单例的,条件如下:
-
如果所有可能的相关 RelTraits 是有限的和固定的。(比如,这个 RelTraitDef 所有的 RelTraits 在编译时都是已知的)例如:
CallingConvention
(调用规约)特征满足这个要求,因为CallingConvention
实际上是一个枚举。以下是调用规约特征的实现: -
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 引擎有 CassandraProject
、CassandraFilter
等关系运算符,这些运算符可以相互连接而不必把数据从一种形式转化为另一种形式。
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 特征。CassandraFilter
、CassandraProject
等关系表达式都满足在 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.
ConverterRule
是 RelOptRule
的子类。两种 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 可能决定交换 Filter 和 Project 节点的顺序。实际上,rule 所做的就是匹配关系代数表达式的子树,并将其替换为不同的子树。