scala – 在Spark Catalyst中从逻辑计划转换为另一个逻辑计划
发布时间:2020-12-16 19:24:04 所属栏目:安全 来源:网络整理
导读:我使用Spark Catalyst来表示 openCypher查询引擎的查询计划,ingraph.在查询计划过程中,我想将某个逻辑计划(Plan1)转换为另一个逻辑计划(Plan2). (我试着把这个问题简单化了,所以我在这里省略了一些细节.该项目完全是开源的,所以如果需要,我很乐意在 why this
我使用Spark Catalyst来表示
openCypher查询引擎的查询计划,ingraph.在查询计划过程中,我想将某个逻辑计划(Plan1)转换为另一个逻辑计划(Plan2). (我试着把这个问题简单化了,所以我在这里省略了一些细节.该项目完全是开源的,所以如果需要,我很乐意在
why this is necessary提供更多信息.)
我能找到的最好的方法是递归地使用transformDown.下面是一个小例子,它通过用OpA2替换每个OpA1实例和用OpB2替换每个OpB1实例,从Plan1Nodes转换为Plan2Nodes. import org.apache.spark.sql.catalyst.expressions.Attribute import org.apache.spark.sql.catalyst.plans.logical.{LeafNode,LogicalPlan,UnaryNode} trait Plan1Node extends LogicalPlan case class OpA1() extends LeafNode with Plan1Node { override def output: Seq[Attribute] = Seq() } case class OpB1(child: Plan1Node) extends UnaryNode with Plan1Node { override def output: Seq[Attribute] = Seq() } trait Plan2Node extends LogicalPlan case class OpA2() extends LeafNode with Plan2Node { override def output: Seq[Attribute] = Seq() } case class OpB2(child: Plan2Node) extends UnaryNode with Plan2Node { override def output: Seq[Attribute] = Seq() } object Plan1ToPlan2 { def transform(plan: Plan1Node): Plan2Node = { plan.transformDown { case OpA1() => OpA2() case OpB1(child) => OpB2(transform(child)) } }.asInstanceOf[Plan2Node] } 这种方法完成了这项工作.这段代码: val p1 = OpB1(OpA1()) val p2 = Plan1ToPlan2.transform(p1) 结果是: p1: OpB1 = OpB1 +- OpA1 p2: Plan2Node = OpB2 +- OpA2 但是,使用asInstanceOf [Plan2Node]肯定是代码中的难闻气味.我考虑使用Strategy来定义转换规则,但该类用于从物理计划转换为逻辑计划. 是否有更优雅的方式来定义逻辑计划之间的转换?或者正在使用被认为是反模式的多个逻辑计划? 解决方法
(回答我自己的问题.)
将transformDown更改为简单模式匹配(匹配)和递归调用解决了类型问题: object Plan1ToPlan2 { def transform(plan: Plan1Node): Plan2Node = { plan match { case OpA1() => OpA2() case OpB1(child) => OpB2(transform(child)) } } } 这似乎是一种类型安全的(基于我对Catalyst的有限理解)惯用解决方案. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |