SparksqlExpression的
刘军连简介 http://baijiahao.baidu.com/s?id=1706675193886405345&wfr=spider&for=pc啥是Expssion? 在sql语句中,除了select、from等关键字以外,其他大部分元素都可以理解为expssion,比如: selecta,bfromtestdatawhea 这里的a,b,,都是expssion Expssion的canonicalized操作这个操作返回经过规范化处理后的表达式 规范化处理会在确保输出结果相同的前提下通过一些规则对表达式进重写 这个规范化有啥用呢?举个例子: selectb,B,sum(A+b)asab,sum(B+a)asbafromtestdatawhebgroupbyb上面的代码中,b和B,sum(A+b)和sum(B+a)虽然在外观上不一样,但实际计算的结果是完全一样的。而规范化操作会把b,B和sum(A+b)和sum(B+a)在外观上统一,这样可以使它们引用同一个实际计算的结果,避免多次计算。 这个规范化具体是怎么操作的呢?借助了工具类:Canonicalize 核心方法execute依据一些规则重写表达式,消除外观差异 defexecute(e:Expssion):Expssion={expssionReorder(ignoNamesTypes(e))}规范化结果集中的命名两种情况: 对于AttributeRefence引用类的表达式,主要做法是消除名称和可空性带来的差异 GetStructField复杂类型的表达式,消除名称带来的差异 对于引用类型的表达式,判断是否相同,只需要引用的id(exprId)是相同的就ok,所以这里的处理方法是把name统一置none,来消除差异,比如: selectb,B,sum(A+b)asab,sum(B+a)asbafromtestdatawhebgroupbyb//name#exprIdExpssion(b)---b#ignoNamesTypes(b)----none#Expssion(B)---B#ignoNamesTypes(B)----none#结过上面转化,b和B都为none#计算类表达式对于交换和结合运算(Add和Multiply)的子运算,通过“hashCode”来对左右子节点排序 对于交换和结合运算(Or和And)的子运算,通过“hashCode”来对左右子节点排序,但要求表达式必须是确定性的 EqualTo和EqualNullSafe通过“hashCode”来对左右子节点排序。 其他比较(gatethan,LessThan)由“hashCode”反转。 in中的元素按`hashCode重新排序 privatedefexpssionReorder(e:Expssion):Expssion=ematch{//加法和乘法可以交换顺序,转换为seq,用Seq的sortBy进行排序casea:Add=orderCommutative(a,{caseAdd(l,r)=Seq(l,r)}).duce(Add)casem:Multiply=orderCommutative(m,{caseMultiply(l,r)=Seq(l,r)}).duce(Multiply)//or和and可以交换顺序,转换为seq,用Seq的sortBy进行排序,但要求必须是确定性的caseo:Or=orderCommutative(o,{caseOr(l,r)ifl.deterministicr.deterministic=Seq(l,r)}).duce(Or)casea:And=orderCommutative(a,{caseAnd(l,r)ifl.deterministicr.deterministic=Seq(l,r)}).duce(And)//EqualTo和EqualNullSafe通过“hashCode”来对左右子节点排序caseEqualTo(l,r)ifl.hashCode()r.hashCode()=EqualTo(r,l)caseEqualNullSafe(l,r)ifl.hashCode()r.hashCode()=EqualNullSafe(r,l)//其他比较gatethan,LessThan由“hashCode”反转,比如在时,如果l.hashCode()r.hashCode(),就转为LessThan(r,l)caseGaterThan(l,r)ifl.hashCode()r.hashCode()=LessThan(r,l)caseLessThan(l,r)ifl.hashCode()r.hashCode()=GaterThan(r,l)caseGaterThanOrEqual(l,r)ifl.hashCode()r.hashCode()=LessThanOrEqual(r,l)caseLessThanOrEqual(l,r)ifl.hashCode()r.hashCode()=GaterThanOrEqual(r,l)//Noteinthefollowing`NOT`cases,`l.hashCode()=r.hashCode()`holds.Theasonisthat//canonicalizationisconductedbottom-up--see[[Expssion.canonicalized]].caseNot(GaterThan(l,r))=LessThanOrEqual(l,r)caseNot(LessThan(l,r))=GaterThanOrEqual(l,r)caseNot(GaterThanOrEqual(l,r))=LessThan(l,r)caseNot(LessThanOrEqual(l,r))=GaterThan(l,r)//in按`hashCode重新排序caseIn(value,list)iflist.length1=In(value,list.sortBy(_.hashCode()))case_=e}}扩展操作semanticEquals//两个表达式计算相同的结果时返回true,判断依据是:两个表达式都确定性的,//且两个表达式规范化之后相同defsemanticEquals(other:Expssion):Boolean=deterministicother.deterministiccanonicalized==other.canonicalizedHey! 我是小萝卜算子 欢迎 |
转载请注明地址:http://www.tanhuaa.com/pzth/10926.html
- 上一篇文章: Python神器Celery源码阅
- 下一篇文章: 没有了