Uh oh!
There was an error while loading. Please reload this page.
[SPARK-26965][SQL] Makes ElementAt nullability more precise for array cases - #23867
[SPARK-26965][SQL] Makes ElementAt nullability more precise for array cases#23867maropu wants to merge 7 commits into
Conversation
SparkQA
commented
Feb 22, 2019
Test build #102617 has finished for PR 23867 at commit
|
dilipbiswal
commented
Feb 22, 2019
retest this please |
SparkQA
commented
Feb 22, 2019
Test build #102630 has finished for PR 23867 at commit
|
maropu
commented
Feb 22, 2019
@dongjoon-hyun could you check? |
| override def toString: String = s"$child[$ordinal]" | ||
| override def sql: String = s"${child.sql}[${ordinal.sql}]" | ||
| trait GetArrayItemUtil extends BinaryExpression { |
There was a problem hiding this comment.
Can we move this after case class GetArrayItem to reduce the diff?
| * Common base class for [[GetMapValue]] and [[ElementAt]]. | ||
| * Common trait for [[GetMapValue]] and [[ElementAt]]. | ||
| */ | ||
| trait GetMapValueUtil extends BinaryExpression with ImplicitCastInputTypes { |
There was a problem hiding this comment.
Does GetMapValueUtil need to extend extends BinaryExpression with ImplicitCastInputTypes? If child and key are required, computeNullabilityFromMap seems to able to accept the child and key as parameters. How do you think that way?
There was a problem hiding this comment.
It seems BinaryExpression.nullSafeCodeGen is used in the other place?
There was a problem hiding this comment.
Thanks. Then, what about GetArrayItemUtil? Actually, the reason why I asked is that this PR makes some non-trivial lineages like the followings.
def BinaryExpression.left->private val GetArrayItemUtil.child->override def GetArrayItem.left.def BinaryExpression.left->private val GetMapValueUtil.child->override def GetMapValue.left
dongjoon-hyun
commented
Feb 25, 2019
Thank you for pinging me, @maropu . I left a few comments. I understand this follows the original code structure, but it seems to become more complicated than the required. |
SparkQA
commented
Feb 25, 2019
Test build #102729 has finished for PR 23867 at commit
|
SparkQA
commented
Feb 26, 2019
Test build #102779 has finished for PR 23867 at commit
|
| /** `Null` is returned for invalid ordinals. */ | ||
| protected def computeNullabilityFromMap: Boolean = if (key.foldable && !key.nullable) { | ||
| val keyObj = key.eval() | ||
| child match { |
There was a problem hiding this comment.
Thank you for updating, @maropu . For this one, can we simplify like the following? We can remove these alias variables.
-privatevalchild= left
-privatevalkey= right
-/** `Null` is returned for invalid ordinals. */-protecteddefcomputeNullabilityFromMap:Boolean=if (key.foldable &&!key.nullable) {
-valkeyObj= key.eval()
- child match {
+protecteddefcomputeNullabilityFromMap:Boolean=if (right.foldable &&!right.nullable) {
+valkeyObj= right.eval()
+ left match {There was a problem hiding this comment.
If you want to keep the clear meaning, you may declare them inside of this function. But, since we are not using parameters, I think we already have some assumptions that this is inside BinaryExpression. So, for me, I just want to avoid making aliases like my previous comment.
protecteddefcomputeNullabilityFromMap:Boolean= {
valchild= left
valkey= right
....
}| case class GetArrayItem(child: Expression, ordinal: Expression) | ||
| extends BinaryExpression with ExpectsInputTypes with ExtractValue with NullIntolerant { | ||
| extends BinaryExpression with GetArrayItemUtil with ExpectsInputTypes with ExtractValue | ||
| with NullIntolerant { |
| checkEvaluation(ElementAt(mb0, Literal(Array[Byte](3, 4))), null) | ||
| } | ||
| test("SPARK-26965 correctly handles ElementAt nullability for arrays") { |
There was a problem hiding this comment.
Since this is a new feature, it seems that we don't need JIRA ID, SPARK-26965, in the test case name.
There was a problem hiding this comment.
I dropped that in the latest commit though, any rule for that?
There was a problem hiding this comment.
Yes. I've heard the rule from @cloud-fan in my old PRs.
I'm not sure if that is a written rule or not.
Hi, @cloud-fan . Do we have some URLs for the above SPARK JIRA ID usage rule in the test case name?
There was a problem hiding this comment.
oh, I see. I'll be more careful next time, thanks!
| since = "2.4.0") | ||
| case class ElementAt(left: Expression, right: Expression) extends GetMapValueUtil { | ||
| case class ElementAt(left: Expression, right: Expression) | ||
| extends GetMapValueUtil with GetArrayItemUtil { |
SparkQA
commented
Mar 1, 2019
Test build #102885 has finished for PR 23867 at commit
|
maropu
commented
Mar 1, 2019
retest this please |
dongjoon-hyun
commented
Mar 1, 2019
+1, LGTM (except one nit comment). Ping, @cloud-fan . |
| left match { | ||
| case m: CreateMap if m.resolved => | ||
| m.keys.zip(m.values).filter { case (k, _) => k.foldable && !k.nullable }.find { | ||
| case (k, _) if k.eval() == keyObj => true |
There was a problem hiding this comment.
can we rely on ==? What if one expression returns unsafe row and the other returns safe row?
I know this is existing code, but after a hindsight maybe it's not worth to linear scan the map entries and just to get the precise nullability.
There was a problem hiding this comment.
I dropped the nullablity computation for the map side and added the TODO comment there. How about this?
SparkQA
commented
Mar 1, 2019
Test build #102897 has finished for PR 23867 at commit
|
SparkQA
commented
Mar 1, 2019
Test build #102901 has finished for PR 23867 at commit
|
| override def nullable: Boolean = true | ||
| override def nullable: Boolean = left.dataType match { | ||
| case _: ArrayType => computeNullabilityFromArray(left, right) | ||
| case _: MapType => computeNullabilityFromMap |
There was a problem hiding this comment.
If Map is out of the scope, shall we update the title and use the following code path instead?
- Remove
extends GetMapValueUtil. - Remove
computeNullabilityFromMapand use the following.
case_: MapType=>true| @@ -381,22 +390,7 @@ case class GetMapValue(child: Expression, key: Expression) | |||
| override def right: Expression = key | |||
| /** `Null` is returned for invalid ordinals. */ | |||
There was a problem hiding this comment.
we need to update this comment, to say why the nullability is always true.
SparkQA
commented
Mar 4, 2019
Test build #102958 has finished for PR 23867 at commit
|
SparkQA
commented
Mar 4, 2019
Test build #102959 has finished for PR 23867 at commit
|
SparkQA
commented
Mar 4, 2019
Test build #102969 has finished for PR 23867 at commit
|
dilipbiswal
commented
Mar 4, 2019
retest this please |
SparkQA
commented
Mar 4, 2019
Test build #102973 has finished for PR 23867 at commit
|
cloud-fan
commented
Mar 4, 2019
thanks, merging to master! |
What changes were proposed in this pull request?
In master,
ElementAtnullable is always true;spark/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/collectionOperations.scala
Line 1977 in be1cadf
But, If input is an array and foldable, we could make its nullability more precise.
This fix is based on SPARK-26637(#23566).
How was this patch tested?
Added tests in
CollectionExpressionsSuite.