Skip to content

Commit 1e29eab

Browse files
committed
Strict argument checks for array() and map()
1 parent 838effb commit 1e29eab

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/complexTypeCreator.scala

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,13 @@ case class CreateArray(children: Seq[Expression]) extends Expression {
4141

4242
override def foldable: Boolean = children.forall(_.foldable)
4343

44-
override def checkInputDataTypes(): TypeCheckResult =
45-
TypeUtils.checkForSameTypeInputExpr(children.map(_.dataType), "function array")
44+
override def checkInputDataTypes(): TypeCheckResult = {
45+
if (children == Nil) {
46+
TypeCheckResult.TypeCheckFailure("input to function coalesce cannot be empty")
47+
} else {
48+
TypeUtils.checkForSameTypeInputExpr(children.map(_.dataType), "function array")
49+
}
50+
}
4651

4752
override def dataType: ArrayType = {
4853
ArrayType(
@@ -168,7 +173,9 @@ case class CreateMap(children: Seq[Expression]) extends Expression {
168173
override def foldable: Boolean = children.forall(_.foldable)
169174

170175
override def checkInputDataTypes(): TypeCheckResult = {
171-
if (children.size % 2 != 0) {
176+
if (children == Nil) {
177+
TypeCheckResult.TypeCheckFailure("input to function coalesce cannot be empty")
178+
} else if (children.size % 2 != 0) {
172179
TypeCheckResult.TypeCheckFailure(s"$prettyName expects a positive even number of arguments.")
173180
} else if (keys.map(_.dataType).distinct.length > 1) {
174181
TypeCheckResult.TypeCheckFailure("The given keys of function map should all be the same " +

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,43 @@ class DataFrameFunctionsSuite extends QueryTest with SharedSQLContext {
448448
rand(Random.nextLong()), randn(Random.nextLong())
449449
).foreach(assertValuesDoNotChangeAfterCoalesceOrUnion(_))
450450
}
451+
452+
test("SPARK-21281 fails if functions have no argument") {
453+
var errMsg = intercept[AnalysisException] {
454+
spark.range(1).select(array())
455+
}.getMessage
456+
assert(errMsg.contains("due to data type mismatch: input to function coalesce cannot be empty"))
457+
458+
errMsg = intercept[AnalysisException] {
459+
spark.range(1).select(map())
460+
}.getMessage
461+
assert(errMsg.contains("due to data type mismatch: input to function coalesce cannot be empty"))
462+
463+
// spark.range(1).select(coalesce())
464+
errMsg = intercept[AnalysisException] {
465+
spark.range(1).select(coalesce())
466+
}.getMessage
467+
assert(errMsg.contains("due to data type mismatch: input to function coalesce cannot be empty"))
468+
469+
// This hits java.lang.AssertionError
470+
// spark.range(1).select(struct())
471+
472+
errMsg = intercept[IllegalArgumentException] {
473+
spark.range(1).select(greatest())
474+
}.getMessage
475+
assert(errMsg.contains("requirement failed: greatest requires at least 2 arguments"))
476+
477+
errMsg = intercept[IllegalArgumentException] {
478+
spark.range(1).select(least())
479+
}.getMessage
480+
assert(errMsg.contains("requirement failed: least requires at least 2 arguments"))
481+
482+
errMsg = intercept[AnalysisException] {
483+
spark.range(1).select(hash())
484+
}.getMessage
485+
assert(errMsg.contains(
486+
"due to data type mismatch: function hash requires at least one argument"))
487+
}
451488
}
452489

453490
object DataFrameFunctionsSuite {

0 commit comments

Comments
 (0)