zoukankan      html  css  js  c++  java
  • Calcite分析 -- Convention&Converter

    Calcite,version:1.26.0

    什么是Convention

    1. 是一种RelTrait,而且是默认必须有的RelTraitDef

    2. 逻辑算子的convention为None,表示未被实现;反过来说物理算子的convention一定不会是None

    在CBO优化前会把root进行convention转换,

      

    改变Convention

    两种方式,

    显式的调用changeTraits,一般只有对于root

    通过convertRule,

    changeTraits

     

    这里对于logicalSort已经注册Subset#3,

    这里调用getOrCreateSubset,目的是什么?

    这里注意一个参数,required=true,什么意思?

    这个代表当前Subset物理属性的状态,

    解释一下?比如排序是一种物理属性,由于parent算子有排序的需求,所以要求,require,当前的算子具有RelCollation的物理属性。

    这里required是true,因为这里的物理属性不是因为他自己或inputs,而是被外部显式调用加上的

     

    这里调用getOrCreateSubset,是因为traits变了,Subset是和traits紧密关联的,

    所以这里生成了新的Subset,

    并且这里还加入了比较复杂的converter的相关逻辑,

    因为在每次Subset的traits发生变化的时候,都需要看看是否需要加入converter,

    这块逻辑其实不应该加在getOrCreateSubset里面,这样很影响可读性

    那么翻译一下,逻辑是啥?

    首先,如果convention==None,逻辑算子,不需要conventer

    其次,如果物理算子,

    新创建的subset,需要conventer

    已有的subset,当required属性发生变化时,需要加converter;即原先不是required,现在是,或原先包含required,现在不是

     

    这里还是唯一会修改state的地方,

    因为当convention改变的时候,肯定是需要生成Subset的,

    逻辑,是如果convention不等于none,那么说明有convention,这里二选一,不是required,其他的都是delivered

    也就是通过RelSet.add,加入一个convention不为none的RelNode时,对应的subset就会被设置成delivered

    为什么?RelSet加入RelNode,大概率是因为rule生成新的算子,如果这个算子带convention,会影响到相应的subset,这个就应该算是delivered;

     

    getOrCreateSubset被调用的主要的两个地方,required的设置是不同的,

    1. 在changeTraits,required设为true,因为显式调用,所以就是required

    2. 在RelSet.add,加入一个RelNode时,只要不是enforcer,required都是false,即大部分情况都是false

    addConverters的逻辑详见,Calcite分析 -- ConverterRule

    总之,这里changeTraits的结果就是增加一个新的traits的Subset,

    注意changeTraits并不会改变RelNode的traitSet,这里仍然是LogicalSort.NONE.[0 DESC-nulls-last],

    为何?在plan用Subset做input,不直接用RelNode,不用转?

    ensureRootConverters

    - 这是唯一处,显式require增加converter的地方;其他地方都是由consumer来require,但是root没有consumer

    - 要求root做在的RelSet中的所有subsets,只要和root的traitSet不同的,都增加一个converter

    理解,要求这样的convention,你如果不满足,就加一层converter去转换成require的convention,满足需求

    什么是,AbstractConverter

    - Converter,用于convert一个Relnode到特定的输出convention

    - AbstractConverter,抽象的,所以后面需要被rule转换成可实现的关系表达式

     注册,有EquivRel,root

    converter在注册的时候,

    不同的地方在于,要判断一下RelSet,

    Converter和他的input,就是需要被转换的RelNode,需要属于同一个RelSet

    注册完的结果,

    AbstractConverter和他的input,RelSubset#3,在一个Relset中

    并且这个RelSet的Parents里面,也加上了这个Converter

      

    在fireRules后,和AbstractConverter相match的rule为,

      

    ExpandConversionRule

    专门用于match,AbstractConverter

    后面在触发的时候看看,具体做了什么

    findBestExp

    重复调用ensureRootConverters,避免没有调用setRoot,直接调用findBestExp?

    这里会把AbstractConverter的input放到subsets中,避免重复加converter

    这里可以看下,root.getRels,这里root是subset是无法直接get到rels的,需要找到Relset先

    这里找到,rels中和subset的traitSet匹配的rels,

    有意思的是,这里强行用linq4j转成Enumerable,使用了一下lambda,再转回iterator返回,秀啊!

  • 相关阅读:
    甲方提供核心jar包,添加到本地maven仓库
    Flexigrid详解
    在idea中使用CheckStyle来规范代码
    对List集合中的对象进行按某个属性排序
    Layui数据表格总结篇
    jQuery入门看这一篇就够了
    JAVA常量类的实现方式
    HTML5和CSS3提高
    CSS高级技巧总结
    CSS入门总结
  • 原文地址:https://www.cnblogs.com/fxjwind/p/15211955.html
Copyright © 2011-2022 走看看