Skip to content

Commit 1d92bdd

Browse files
juliuszsompolskiMingjie Tang
authored andcommitted
[SPARK-20412] Throw ParseException from visitNonOptionalPartitionSpec instead of returning null values.
## What changes were proposed in this pull request? If a partitionSpec is supposed to not contain optional values, a ParseException should be thrown, and not nulls returned. The nulls can later cause NullPointerExceptions in places not expecting them. ## How was this patch tested? A query like "SHOW PARTITIONS tbl PARTITION(col1='val1', col2)" used to throw a NullPointerException. Now it throws a ParseException. Author: Juliusz Sompolski <[email protected]> Closes apache#17707 from juliuszsompolski/SPARK-20412.
1 parent 0001603 commit 1d92bdd

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,10 @@ class AstBuilder extends SqlBaseBaseVisitor[AnyRef] with Logging {
215215
*/
216216
protected def visitNonOptionalPartitionSpec(
217217
ctx: PartitionSpecContext): Map[String, String] = withOrigin(ctx) {
218-
visitPartitionSpec(ctx).mapValues(_.orNull).map(identity)
218+
visitPartitionSpec(ctx).map {
219+
case (key, None) => throw new ParseException(s"Found an empty partition key '$key'.", ctx)
220+
case (key, Some(value)) => key -> value
221+
}
219222
}
220223

221224
/**

sql/core/src/test/scala/org/apache/spark/sql/execution/command/DDLCommandSuite.scala

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -530,13 +530,13 @@ class DDLCommandSuite extends PlanTest {
530530
""".stripMargin
531531
val sql4 =
532532
"""
533-
|ALTER TABLE table_name PARTITION (test, dt='2008-08-08',
533+
|ALTER TABLE table_name PARTITION (test=1, dt='2008-08-08',
534534
|country='us') SET SERDE 'org.apache.class' WITH SERDEPROPERTIES ('columns'='foo,bar',
535535
|'field.delim' = ',')
536536
""".stripMargin
537537
val sql5 =
538538
"""
539-
|ALTER TABLE table_name PARTITION (test, dt='2008-08-08',
539+
|ALTER TABLE table_name PARTITION (test=1, dt='2008-08-08',
540540
|country='us') SET SERDEPROPERTIES ('columns'='foo,bar', 'field.delim' = ',')
541541
""".stripMargin
542542
val parsed1 = parser.parsePlan(sql1)
@@ -558,12 +558,12 @@ class DDLCommandSuite extends PlanTest {
558558
tableIdent,
559559
Some("org.apache.class"),
560560
Some(Map("columns" -> "foo,bar", "field.delim" -> ",")),
561-
Some(Map("test" -> null, "dt" -> "2008-08-08", "country" -> "us")))
561+
Some(Map("test" -> "1", "dt" -> "2008-08-08", "country" -> "us")))
562562
val expected5 = AlterTableSerDePropertiesCommand(
563563
tableIdent,
564564
None,
565565
Some(Map("columns" -> "foo,bar", "field.delim" -> ",")),
566-
Some(Map("test" -> null, "dt" -> "2008-08-08", "country" -> "us")))
566+
Some(Map("test" -> "1", "dt" -> "2008-08-08", "country" -> "us")))
567567
comparePlans(parsed1, expected1)
568568
comparePlans(parsed2, expected2)
569569
comparePlans(parsed3, expected3)
@@ -832,6 +832,14 @@ class DDLCommandSuite extends PlanTest {
832832
assert(e.contains("Found duplicate keys 'a'"))
833833
}
834834

835+
test("empty values in non-optional partition specs") {
836+
val e = intercept[ParseException] {
837+
parser.parsePlan(
838+
"SHOW PARTITIONS dbx.tab1 PARTITION (a='1', b)")
839+
}.getMessage
840+
assert(e.contains("Found an empty partition key 'b'"))
841+
}
842+
835843
test("drop table") {
836844
val tableName1 = "db.tab"
837845
val tableName2 = "tab"

0 commit comments

Comments
 (0)