Uh oh!
There was an error while loading. Please reload this page.
[SPARK-18251][SQL] the type of Dataset can't be Option of non-flat type - #15979
[SPARK-18251][SQL] the type of Dataset can't be Option of non-flat type#15979cloud-fan wants to merge 3 commits into
Conversation
cloud-fan
commented
Nov 22, 2016
SparkQA
commented
Nov 22, 2016
Test build #69000 has finished for PR 15979 at commit
|
rxin
commented
Nov 22, 2016
What does "non-flat type" mean? |
cloud-fan
commented
Nov 23, 2016
"non-flat type" means "complex type", i.e. array, seq, map, product, etc. |
cloud-fan
commented
Nov 28, 2016
retest it please |
There was a problem hiding this comment.
Let's provide an example in the error message to help users understand how to handle this case.
yhuai
commented
Nov 29, 2016
looks good. @liancheng want to double check? |
SparkQA
commented
Nov 29, 2016
Test build #69326 has finished for PR 15979 at commit
|
cloud-fan
commented
Nov 29, 2016
retest this please |
SparkQA
commented
Nov 29, 2016
Test build #69328 has finished for PR 15979 at commit
|
liancheng
commented
Nov 29, 2016
My only concern is that "non-flat" type is neither intuitive nor a well-known term. In fact, this PR only prevents Otherwise LGTM. |
rxin
commented
Nov 29, 2016
FWIW I don't think we should call it nonflat. |
SparkQA
commented
Nov 30, 2016
Test build #69387 has started for PR 15979 at commit |
cloud-fan
commented
Nov 30, 2016
retest this please |
liancheng
commented
Nov 30, 2016
Good to merge pending Jenkins. Thanks! |
SparkQA
commented
Nov 30, 2016
Test build #69394 has finished for PR 15979 at commit
|
cloud-fan
commented
Nov 30, 2016
retest this please |
SparkQA
commented
Nov 30, 2016
Test build #69403 has finished for PR 15979 at commit
|
SparkQA
commented
Nov 30, 2016
Test build #69411 has finished for PR 15979 at commit
|
liancheng
commented
Nov 30, 2016
Merging to master. Thanks! |
liancheng
commented
Nov 30, 2016
@rxin Shall we backport this to branch-2.1? I think it's relatively safe. |
rxin
commented
Nov 30, 2016
Sounds good. |
liancheng
commented
Nov 30, 2016
Also backported to branch-2.1. |
## What changes were proposed in this pull request? For input object of non-flat type, we can't encode it to row if it's null, as Spark SQL doesn't allow the entire row to be null, only its columns can be null. That's the reason we forbid users to use top level null objects in #13469 However, if users wrap non-flat type with `Option`, then we may still encoder top level null object to row, which is not allowed. This PR fixes this case, and suggests users to wrap their type with `Tuple1` if they do wanna top level null objects. ## How was this patch tested? new test Author: Wenchen Fan <wenchen@databricks.com> Closes#15979 from cloud-fan/option. (cherry picked from commit f135b70) Signed-off-by: Cheng Lian <lian@databricks.com>
## What changes were proposed in this pull request? For input object of non-flat type, we can't encode it to row if it's null, as Spark SQL doesn't allow the entire row to be null, only its columns can be null. That's the reason we forbid users to use top level null objects in apache#13469 However, if users wrap non-flat type with `Option`, then we may still encoder top level null object to row, which is not allowed. This PR fixes this case, and suggests users to wrap their type with `Tuple1` if they do wanna top level null objects. ## How was this patch tested? new test Author: Wenchen Fan <wenchen@databricks.com> Closesapache#15979 from cloud-fan/option.
| if (ScalaReflection.optionOfProductType(tpe)) { | ||
| throw new UnsupportedOperationException( | ||
| "Cannot create encoder for Option of Product type, because Product type is represented " + |
There was a problem hiding this comment.
this also means an Aggregator cannot use an Option of Product Type for its intermediate type. e.g.
Aggregator[Int, Option[(Int, Int)], Int] is now invalid. but i see no good reason why such an Aggregator wouldnt exist?
There was a problem hiding this comment.
this strikes me more as a limitation on Dataset[X] than on Encoder[X]
There was a problem hiding this comment.
and now that i think about it more, i also think Dataset[Option[(Int, Int)]] should be valid too if possible.
it should not be represented by a top level Row object, so the schema should beStructType(StructField("_1", StructType(StructField("_1", IntegerType, false), StructField("_2", IntegerType, false)), true))
we do this trick where we nest top-level non-struct types inside a row, why not do the same thing for Option[X <: Product]?
koertkuipers
commented
Dec 4, 2016
this means anything that uses an encoder can no longer use Option[_ <: Product]. Dataset.groupByKey[K] requires an encoder for K. none of these always create top level row objects (for which this pullreq creates the restriction that they cannot be null). for an aggregator it is sometimes the case. so i am not sure it makes sense to put this restriction on the encoder. it seems to belong on the dataset. another example of something that won't work anymore: in this case the mapValues requires |
Does it work before? Please see the discussion in the JIRA: https://issues.apache.org/jira/browse/SPARK-18251 It's still possible to support |
koertkuipers
commented
Dec 4, 2016
via email
Yes it worked before …On Dec 4, 2016 02:33, "Wenchen Fan" ***@***.***> wrote:
val x: Dataset[String, Option[(String, String)]] = ...
x.groupByKey(_._1).mapValues(_._2).agg(someAgg)
Does it work before?
Please see the discussion in the JIRA: https://issues.apache.org/
jira/browse/SPARK-18251
Ideally we have a map between type T and catalyst schema, and Option[T]
maps to the same catalyst schema with T, with additional null handling.
We shouldn't change this mapping, which means we can't use a single field
struct type to represent Option[T].
It's still possible to support Option[T] completely(without breaking
backward compatibility), but that may need a lof of hacky code and special
handling, I don't think it worth, as we can easy work around it, by Tuple1
.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#15979 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAyIJD-_dmJODKn5_k8MHRFaJkHvL9uRks5rEmzCgaJpZM4K5fEL>
.
|
koertkuipers
commented
Dec 4, 2016
via email
spark 2.0.x does not have mapValues. but this works:
scala> Seq(("a", Some((1, 1))), ("a",
None)).toDS.groupByKey(_._2).count.show
+-----------+--------+
| key|count(1)|
+-----------+--------+
|[null,null]| 1|
| [1,1]| 1|
+-----------+--------+ …On Sun, Dec 4, 2016 at 9:59 AM, Koert Kuipers ***@***.***> wrote:
Yes it worked before
On Dec 4, 2016 02:33, "Wenchen Fan" ***@***.***> wrote:
> val x: Dataset[String, Option[(String, String)]] = ...
> x.groupByKey(_._1).mapValues(_._2).agg(someAgg)
>
> Does it work before?
>
> Please see the discussion in the JIRA: https://issues.apache.org/jira
> /browse/SPARK-18251
> Ideally we have a map between type T and catalyst schema, and Option[T]
> maps to the same catalyst schema with T, with additional null handling.
> We shouldn't change this mapping, which means we can't use a single field
> struct type to represent Option[T].
>
> It's still possible to support Option[T] completely(without breaking
> backward compatibility), but that may need a lof of hacky code and special
> handling, I don't think it worth, as we can easy work around it, by
> Tuple1.
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <#15979 (comment)>, or mute
> the thread
> <https://github.com/notifications/unsubscribe-auth/AAyIJD-_dmJODKn5_k8MHRFaJkHvL9uRks5rEmzCgaJpZM4K5fEL>
> .
>
|
koertkuipers
commented
Dec 4, 2016
via email
admittedly the result looks weird. it really should be:
+-----------+--------+
| key|count(1)|
+-----------+--------+
| null| 1|
| [1,1]| 1|
+-----------+--------+
is that a separate bug or related? i remember running into this before,
because serializing and then deserializing None comes back out as
Some((null, null)), which causes NPE in codegen. i ran into this with
Aggregator buffers. …On Sun, Dec 4, 2016 at 12:13 PM, Koert Kuipers ***@***.***> wrote:
spark 2.0.x does not have mapValues. but this works:
scala> Seq(("a", Some((1, 1))), ("a", None)).toDS.groupByKey(_._2).
count.show
+-----------+--------+
| key|count(1)|
+-----------+--------+
|[null,null]| 1|
| [1,1]| 1|
+-----------+--------+
On Sun, Dec 4, 2016 at 9:59 AM, Koert Kuipers ***@***.***> wrote:
> Yes it worked before
>
> On Dec 4, 2016 02:33, "Wenchen Fan" ***@***.***> wrote:
>
>> val x: Dataset[String, Option[(String, String)]] = ...
>> x.groupByKey(_._1).mapValues(_._2).agg(someAgg)
>>
>> Does it work before?
>>
>> Please see the discussion in the JIRA: https://issues.apache.org/jira
>> /browse/SPARK-18251
>> Ideally we have a map between type T and catalyst schema, and Option[T]
>> maps to the same catalyst schema with T, with additional null handling.
>> We shouldn't change this mapping, which means we can't use a single field
>> struct type to represent Option[T].
>>
>> It's still possible to support Option[T] completely(without breaking
>> backward compatibility), but that may need a lof of hacky code and special
>> handling, I don't think it worth, as we can easy work around it, by
>> Tuple1.
>>
>> —
>> You are receiving this because you commented.
>> Reply to this email directly, view it on GitHub
>> <#15979 (comment)>, or mute
>> the thread
>> <https://github.com/notifications/unsubscribe-auth/AAyIJD-_dmJODKn5_k8MHRFaJkHvL9uRks5rEmzCgaJpZM4K5fEL>
>> .
>>
>
|
## What changes were proposed in this pull request? For input object of non-flat type, we can't encode it to row if it's null, as Spark SQL doesn't allow the entire row to be null, only its columns can be null. That's the reason we forbid users to use top level null objects in apache#13469 However, if users wrap non-flat type with `Option`, then we may still encoder top level null object to row, which is not allowed. This PR fixes this case, and suggests users to wrap their type with `Tuple1` if they do wanna top level null objects. ## How was this patch tested? new test Author: Wenchen Fan <wenchen@databricks.com> Closesapache#15979 from cloud-fan/option.
What changes were proposed in this pull request?
For input object of non-flat type, we can't encode it to row if it's null, as Spark SQL doesn't allow the entire row to be null, only its columns can be null. That's the reason we forbid users to use top level null objects in #13469
However, if users wrap non-flat type with
Option, then we may still encoder top level null object to row, which is not allowed.This PR fixes this case, and suggests users to wrap their type with
Tuple1if they do wanna top level null objects.How was this patch tested?
new test