ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

SparkSQL Catalyst中的TreeNode

2022-06-28 22:02:17  阅读:142  来源: 互联网

标签:case TreeNode BaseType child SparkSQL LogicalPlan Aggregate Catalyst


引言

Scala Product、case类和元组

case 关键字不仅可以推断出val,同时自动增加一些方法,那么增加了那些方法呢?

你定义的case 类会混入scala.Product 特征,它提供了几个关于实例字段的通用方法。例如,对于Person 的实例:

package cn.com.tengen.test.obj
case class Person(name: String,age: Option[Int] = None)
 
object Person extends App{
  val p = Person("Lucky",Option(18))
  println(p.productArity) //元素的个数            输出:2
  println(p.productElement(0))//第1个元素         输出:Lucky
  println(p.productElement(1))//第二个元素        输出:Some(18)
  p.productIterator foreach println//便利         输出:Lucky  Some(18)
}

可以通过Product特征的方法来获取Case类的各个属性以及对应的一些操作(大小size、第n个元素值等)

简介

TreeNode累是Catalyst中和执行计划相关的所有AST,包括表达式Expression、逻辑执行计划LogicalPlan,物理执行计划SparkPlan的基类。

TreeNode继承Scala中的Product类,其目的是可通过Product类中的方法(productArity、productElement、productIterator)来操纵TreeNode实现类的参数,这些实现类一般都是case class。

TreeNode是抽象类,用于被其他抽象或实现类继承,如Expression、LogicalPlan。TreeNode类声明如下:

abstract class TreeNode[BaseType <: TreeNode[BaseType]] extends Product

并且定义了this的别名:

  self: BaseType =>

这里约定TreeNode的泛型参数类型BaseType应是TreeNode[BasType]的子类型,并且继承TreeNode的实现类的类型就是传入的BaseType。比如Aggregate是LogicalPlan的实现类,LogicalPlan继承QueryPlan[LogicalPlan],又有QueryPlan[PlanType <: QueryPlan[PlanType]]继承TreeNode[PlanType],因此Aggregate的self类型就是Aggregate。

通过Product方法获取Case类属性值

如Aggregate类:

case class Aggregate(
      groupingExpressions: Seq[Expression],
      aggregateExpressions: Seq[NamedExpression],
      child: LogicalPlan)
    extends UnaryNode { ... }
abstract class UnaryNode extends LogicalPlan { ... }

在TreeNode源码中:

  protected def mapProductIterator[B: ClassTag](f: Any => B): Array[B] = {
    val arr = Array.ofDim[B](productArity) // Aggregate的属性size=3
    var i = 0
    while (i < arr.length) {
      arr(i) = f(productElement(i))  // 遍历Aggregate的每个属性(groupingExpressions,aggregateExpressions,child)
      i += 1
    }
    arr
  }

TreeNode源码mapChildren方法中:

Aggregate类中的child属性会被匹配到(child继承 -> LogicalPlan继承 -> TreeNode )

def mapChildren(f: BaseType => BaseType): BaseType = {
    if (children.nonEmpty) {
      var changed = false
      val newArgs = mapProductIterator {
        case arg: TreeNode[_] if containsChild(arg) =>   // Aggregate类中的child属性会被匹配到(child继承 -> LogicalPlan继承 -> TreeNode )
          val newChild = f(arg.asInstanceOf[BaseType])
          if (!(newChild fastEquals arg)) {
            changed = true
            newChild
          } else {
            arg
          }
        
        ...
        }
    }
}

 

标签:case,TreeNode,BaseType,child,SparkSQL,LogicalPlan,Aggregate,Catalyst
来源: https://www.cnblogs.com/limaosheng/p/16421295.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有