Skip to content

Commit c4a6519

Browse files
dongjoon-hyungatorsmile
authored andcommitted
[SPARK-19218][SQL] Fix SET command to show a result correctly and in a sorted order
## What changes were proposed in this pull request? This PR aims to fix the following two things. 1. `sql("SET -v").collect()` or `sql("SET -v").show()` raises the following exceptions for String configuration with default value, `null`. For the test, please see [Jenkins result](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/71539/testReport/) and 60953bf in #16624 . ``` sbt.ForkMain$ForkError: java.lang.RuntimeException: Error while decoding: java.lang.NullPointerException createexternalrow(input[0, string, false].toString, input[1, string, false].toString, input[2, string, false].toString, StructField(key,StringType,false), StructField(value,StringType,false), StructField(meaning,StringType,false)) :- input[0, string, false].toString : +- input[0, string, false] :- input[1, string, false].toString : +- input[1, string, false] +- input[2, string, false].toString +- input[2, string, false] ``` 2. Currently, `SET` and `SET -v` commands show unsorted result. We had better show a sorted result for UX. Also, this is compatible with Hive. **BEFORE** ``` scala> sql("set").show(false) ... |spark.driver.host |10.22.16.140 | |spark.driver.port |63893 | |spark.repl.class.uri |spark://10.22.16.140:63893/classes | ... |spark.app.name |Spark shell | |spark.driver.memory |4G | |spark.executor.id |driver | |spark.submit.deployMode |client | |spark.master |local[*] | |spark.home |/Users/dhyun/spark | |spark.sql.catalogImplementation|hive | |spark.app.id |local-1484333618945 | ``` **AFTER** ``` scala> sql("set").show(false) ... |spark.app.id |local-1484333925649 | |spark.app.name |Spark shell | |spark.driver.host |10.22.16.140 | |spark.driver.memory |4G | |spark.driver.port |64994 | |spark.executor.id |driver | |spark.jars | | |spark.master |local[*] | |spark.repl.class.uri |spark://10.22.16.140:64994/classes | |spark.sql.catalogImplementation|hive | |spark.submit.deployMode |client | ``` ## How was this patch tested? Jenkins with a new test case. Author: Dongjoon Hyun <[email protected]> Closes #16579 from dongjoon-hyun/SPARK-19218.
1 parent f067ace commit c4a6519

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

sql/core/src/main/scala/org/apache/spark/sql/execution/command/SetCommand.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,17 @@ case class SetCommand(kv: Option[(String, Option[String])]) extends RunnableComm
7979
// Queries all key-value pairs that are set in the SQLConf of the sparkSession.
8080
case None =>
8181
val runFunc = (sparkSession: SparkSession) => {
82-
sparkSession.conf.getAll.map { case (k, v) => Row(k, v) }.toSeq
82+
sparkSession.conf.getAll.toSeq.sorted.map { case (k, v) => Row(k, v) }
8383
}
8484
(keyValueOutput, runFunc)
8585

8686
// Queries all properties along with their default values and docs that are defined in the
8787
// SQLConf of the sparkSession.
8888
case Some(("-v", None)) =>
8989
val runFunc = (sparkSession: SparkSession) => {
90-
sparkSession.sessionState.conf.getAllDefinedConfs.map { case (key, defaultValue, doc) =>
91-
Row(key, defaultValue, doc)
90+
sparkSession.sessionState.conf.getAllDefinedConfs.sorted.map {
91+
case (key, defaultValue, doc) =>
92+
Row(key, Option(defaultValue).getOrElse("<undefined>"), doc)
9293
}
9394
}
9495
val schema = StructType(

sql/core/src/main/scala/org/apache/spark/sql/internal/SQLConf.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ object SQLConf {
5050
sqlConfEntries.put(entry.key, entry)
5151
}
5252

53+
// For testing only
54+
private[sql] def unregister(entry: ConfigEntry[_]): Unit = sqlConfEntries.synchronized {
55+
sqlConfEntries.remove(entry.key)
56+
}
57+
5358
private[sql] object SQLConfigBuilder {
5459

5560
def apply(key: String): ConfigBuilder = new ConfigBuilder(key).onCreate(register)

sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,33 @@ class SQLQuerySuite extends QueryTest with SharedSQLContext {
982982
spark.sessionState.conf.clear()
983983
}
984984

985+
test("SPARK-19218 SET command should show a result in a sorted order") {
986+
val overrideConfs = sql("SET").collect()
987+
sql(s"SET test.key3=1")
988+
sql(s"SET test.key2=2")
989+
sql(s"SET test.key1=3")
990+
val result = sql("SET").collect()
991+
assert(result ===
992+
(overrideConfs ++ Seq(
993+
Row("test.key1", "3"),
994+
Row("test.key2", "2"),
995+
Row("test.key3", "1"))).sortBy(_.getString(0))
996+
)
997+
spark.sessionState.conf.clear()
998+
}
999+
1000+
test("SPARK-19218 `SET -v` should not fail with null value configuration") {
1001+
import SQLConf._
1002+
val confEntry = SQLConfigBuilder("spark.test").doc("doc").stringConf.createWithDefault(null)
1003+
1004+
try {
1005+
val result = sql("SET -v").collect()
1006+
assert(result === result.sortBy(_.getString(0)))
1007+
} finally {
1008+
SQLConf.unregister(confEntry)
1009+
}
1010+
}
1011+
9851012
test("SET commands with illegal or inappropriate argument") {
9861013
spark.sessionState.conf.clear()
9871014
// Set negative mapred.reduce.tasks for automatically determining

0 commit comments

Comments
 (0)