Calcite的VolcanoPlanner调用流程简介
文章目录
- 前言
- VolcanoPlanner
- changeTraits
- setRoot
- findBestExp
- 总结
前言
之前分析过HepPlanner的调用以及Graph的变化,这次再来看看VolcanoPlanner的的调用和RelSet的变化
VolcanoPlanner
从VolcanoPlannerTest的单测不难发现,提供给用户直接调用的接口主要是changeTraits、setRoot、findBestExp三个

实际上更这三个方法都被封装在了Programs中,用户一般直接使用Programs#run或者实现自己的Programs去调用这三个方法。

changeTraits
changeTraits不只是会改变traits,也调用ensureRegistered方法注册每个RelNode

- ensureRegistered
初次注册还没有对应的subset会直接走到register,否则会走到canonize
如果有等价的subset,还会用
merge方法合并两个等价的subset

- register
同样register只有在无等价的RelNode时才会调用registerImpl,有的话会调用ensureRegistered形成递归(传入的equivRel为null只会递归一层下一层就走不到了)

当ensureRegistered执行完,VolcanoPlanner已经持有每个RelNode对应的RelSet
- allSets是所有RelSet构成的List
- mapDigestToRel是RelDigest到RelNode的映射
- mapRel2Subset是RelNode到RelSubset的映射(RelSubset引用RelSet)
RelSubset中的RelNode有相同的traits,是RelSet的子集

setRoot
setRoot并没有ensureRegistered那么复杂,而是直接调用到了registerImpl

如果是RelSubset调用registerSubset,否则会走一些列对RelNode处理
- 首先调用
onRegister确保RelNode都已注册,onRegister还会调用到刚刚提过的ensureRegistered

- 然后会往mapDigestToRel、mapDigestToRel添加映射

最后会激活RelNode对应的规则
IterativeRuleQueue#addMatch将规则暂时存到了队列中

findBestExp
trait和root都设置好了可以开始找最优的计划了。ensureRootConverters确保根的转换registerMaterializations注册物化相关的RelNode,ruleDriver.drive()会使用优化规则进行转换

将规则从ruleQueue取出(注册RelNode的时候放入的),调用到相应规则的onMatch方法

需要转换的时候会调用transformTo,transformTo也会触发新节点的注册(RelSubSet就会添加等价的RelNode,之后从等价的中找最优计划)
有些RelRule的
onMatch方法进入后,判断完不适合转换会提前return不会调用transformTo

总结
用dot图来表示如下:changeTraits、setRoot主要是在注册RelNode激活对应的规则放入IterativeRuleDriver,findBestExp从IterativeRuleDriver取出规则并应用。
因为注册的时候是递归调用,而且要考虑RelNode和RelSubSet,RelSubSet还要考虑是否等价,所以调用流程非常复杂。

附上dot的源码
# http://www.graphviz.org/content/clusterdigraph G {subgraph cluster_0 {changeTraits -> ensureRegistered ;onRegister -> ensureRegistered;registerImpl -> onRegister;registerImpl -> registerSubset[label = "RelSubset "];registerImpl -> addRelToSet;registerImpl -> "apDigestToRel.putIfAbsent";registerImpl -> fireRule; subgraph cluster_2 {label = "not RelSubset"onRegister;addRelToSet;"apDigestToRel.putIfAbsent";fireRule;}register -> ensureRegistered[label = "equivRel!=null"];register -> registerImpl[label = "equivRel==null"];ensureRegistered -> register[label = "subset==null" ];ensureRegistered -> merge[label = "equivRel!=null "] ;ensureRegistered -> canonize;subgraph cluster_1 {label = "subset!=null " merge;canonize;}findBestExp -> ensureRootConverters;ensureRootConverters -> register[label = "AbstractConverter"];findBestExp -> registerMaterializations -> registerImpl;setRoot -> registerImpl;subgraph cluster_3 {label = "";changeTraits;setRoot;findBestExp;}label = "VolcanoPlanner";}fireRule -> addMatch[label = "......"];subgraph cluster_4 {label = "IterativeRuleQueue";"popMatch";"addMatch"}findBestExp -> "drive";"drive" -> "popMatch";"drive" -> "match.onMatch" -> "getRule().onMatch";"getRule().onMatch" -> "transformTo"[label = "......"];transformTo -> ensureRegistered[label = "......"];subgraph cluster_5 {label = "IterativeRuleDriver";drive}subgraph cluster_6 {label = "VolcanoRuleMatch""match.onMatch"}subgraph cluster_7 {label = "ConverterRule""getRule().onMatch"}subgraph cluster_8 {label = "RelOptRuleCall""transformTo"}
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
