Uh oh!
There was an error while loading. Please reload this page.
[SPARK-20018][SQL] Pivot with timestamp and count should not print internal representation - #17348
[SPARK-20018][SQL] Pivot with timestamp and count should not print internal representation#17348HyukjinKwon wants to merge 4 commits into
Conversation
HyukjinKwon
commented
Mar 19, 2017
cc @aray and @cloud-fan, could you take a look and see if it makes sense? |
aray
commented
Mar 19, 2017
LGTM |
HyukjinKwon
commented
Mar 19, 2017
Thank you for your sign-off @aray. |
SparkQA
commented
Mar 19, 2017
Test build #74824 has finished for PR 17348 at commit
|
| val singleAgg = aggregates.size == 1 | ||
| def outputName(value: Literal, aggregate: Expression): String = { | ||
| val scalaValue = CatalystTypeConverters.convertToScala(value.value, value.dataType) | ||
| val stringValue = Option(scalaValue).getOrElse("null").toString |
There was a problem hiding this comment.
The impact is not only on the data type timestamp. Any test case to cover null?
There was a problem hiding this comment.
Maybe, I thought https://github.com/HyukjinKwon/spark/blob/3c619dfb94723bd7a7d6a0811ab6329bf107f81b/sql/core/src/test/scala/org/apache/spark/sql/DataFramePivotSuite.scala#L220-L232 covers this.
Literal.toString handles null case before. If we remove Option(...).getOrElse("null") there, it throws NPE in those tests.
ueshin
commented
Mar 22, 2017
What if session local timezone is changed? |
@ueshin, you are right. I think we should consider the timezone. valtimestamp= java.sql.Timestamp.valueOf("2012-12-31 16:00:10.011")
spark.conf.set("spark.sql.session.timeZone", "America/Los_Angeles")
Seq(timestamp).toDF("a").groupBy("a").pivot("a").count().show() |
| case Pivot(groupByExprs, pivotColumn, pivotValues, aggregates, child) => | ||
| val singleAgg = aggregates.size == 1 | ||
| def outputName(value: Literal, aggregate: Expression): String = { | ||
| val utf8Value = Cast(value, StringType, Some(conf.sessionLocalTimeZone)).eval(EmptyRow) |
There was a problem hiding this comment.
It seems we can cast into StringType in all the ways -
There was a problem hiding this comment.
BTW, is this a correct way for handling timezone - @ueshin ?
There was a problem hiding this comment.
Thank you for your confirmation.
SparkQA
commented
Mar 22, 2017
Test build #75018 has finished for PR 17348 at commit
|
| val df = Seq(java.sql.Timestamp.valueOf(ts)).toDF("a").groupBy("a").pivot("a").count() | ||
| val expected = StructType( | ||
| StructField("a", TimestampType) :: | ||
| StructField(tsWithZone, LongType) :: Nil) |
There was a problem hiding this comment.
is it expected? users will see different values now
There was a problem hiding this comment.
Yea, I was confused of it too because the original values are apprently rendered differently. However, it seems intended.
scala> spark.conf.set("spark.sql.session.timeZone", "America/Los_Angeles")
scala>valtimestamp= java.sql.Timestamp.valueOf("2012-12-31 16:00:10.011")
timestamp: java.sql.Timestamp=2012-12-3116:00:10.011
scala>Seq(timestamp).toDF("a").show()
+--------------------+| a|+--------------------+|2012-12-3023:00:...|+--------------------+Internal values seem as they are but it seems only changing human readable format according to the given timezone.
I guess this is as described in #16308
There was a problem hiding this comment.
the column name changes with timezone, but what about the value? can you also check the result?
There was a problem hiding this comment.
Ah, sure.
scala>valtimestamp= java.sql.Timestamp.valueOf("2012-12-31 16:00:10.011")
timestamp: java.sql.Timestamp=2012-12-3116:00:10.011
scala> spark.conf.set("spark.sql.session.timeZone", "America/Los_Angeles")
scala>Seq(timestamp).toDF("a").groupBy("a").pivot("a").count().show(false)
+-----------------------+-----------------------+|a |2012-12-3023:00:10.011|+-----------------------+-----------------------+|2012-12-3023:00:10.011|1|+-----------------------+-----------------------+There was a problem hiding this comment.
With the default timezone ...
scala>valtimestamp= java.sql.Timestamp.valueOf("2012-12-31 16:00:10.011")
timestamp: java.sql.Timestamp=2012-12-3116:00:10.011
scala>Seq(timestamp).toDF("a").groupBy("a").pivot("a").count().show(false)
+-----------------------+-----------------------+|a |2012-12-3116:00:10.011|+-----------------------+-----------------------+|2012-12-3116:00:10.011|1|+-----------------------+-----------------------+There was a problem hiding this comment.
Few more tests with string cast ...
scala>valtimestamp= java.sql.Timestamp.valueOf("2012-12-31 16:00:10.011")
timestamp: java.sql.Timestamp=2012-12-3116:00:10.011
scala>Seq(timestamp).toDF("a").groupBy("a").pivot("a").count().selectExpr("cast(a as string)", "`2012-12-31 16:00:10.011`").show(false)
+-----------------------+-----------------------+|a |2012-12-3116:00:10.011|+-----------------------+-----------------------+|2012-12-3116:00:10.011|1|+-----------------------+-----------------------+scala> spark.conf.set("spark.sql.session.timeZone", "America/Los_Angeles")
scala>valtimestamp= java.sql.Timestamp.valueOf("2012-12-31 16:00:10.011")
timestamp: java.sql.Timestamp=2012-12-3116:00:10.011
scala>Seq(timestamp).toDF("a").groupBy("a").pivot("a").count().selectExpr("cast(a as string)", "`2012-12-30 23:00:10.011`").show(false)
+-----------------------+-----------------------+|a |2012-12-3023:00:10.011|+-----------------------+-----------------------+|2012-12-3023:00:10.011|1|+-----------------------+-----------------------+SparkQA
commented
Mar 22, 2017
Test build #75019 has finished for PR 17348 at commit
|
| val expected = StructType( | ||
| StructField("a", TimestampType) :: | ||
| StructField(tsWithZone, LongType) :: Nil) | ||
| assert(df.schema == expected) |
There was a problem hiding this comment.
can we add a checkAnswer to make sure the value is also tsWithZone?
cloud-fan
commented
Mar 22, 2017
LGTM |
SparkQA
commented
Mar 22, 2017
Test build #75051 has finished for PR 17348 at commit
|
gatorsmile
commented
Mar 22, 2017
Thanks! Merging to master. |
What changes were proposed in this pull request?
Currently, when we perform count with timestamp types, it prints the internal representation as the column name as below:
This PR proposes to use external Scala value instead of the internal representation in the column names as below:
How was this patch tested?
Unit test in
DataFramePivotSuiteand manual tests.