[SPARK-14023][CORE][SQL] Don't reference 'field' in StructField errors for clarity in exceptions

## What changes were proposed in this pull request?

Variation of https://github.com/apache/spark/pull/20500
I cheated by not referencing fields or columns at all as this exception propagates in contexts where both would be applicable.

## How was this patch tested?

Existing tests

Closes #23373 from srowen/SPARK-14023.2.

Authored-by: Sean Owen <sean.owen@databricks.com>
Signed-off-by: Dongjoon Hyun <dongjoon@apache.org>
This commit is contained in:
Sean Owen 2018-12-23 21:09:44 -08:00 committed by Dongjoon Hyun
parent 1008ab0801
commit 0523f5e378
No known key found for this signature in database
GPG key ID: EDA00CE834F0FC5C
2 changed files with 11 additions and 14 deletions

View file

@ -28,7 +28,6 @@ import org.apache.spark.annotation.Stable
import org.apache.spark.sql.catalyst.expressions.{Attribute, AttributeReference, InterpretedOrdering}
import org.apache.spark.sql.catalyst.parser.{CatalystSqlParser, LegacyTypeStringParser}
import org.apache.spark.sql.catalyst.util.{quoteIdentifier, truncatedString}
import org.apache.spark.util.Utils
/**
* A [[StructType]] object can be constructed by
@ -57,7 +56,7 @@ import org.apache.spark.util.Utils
*
* // If this struct does not have a field called "d", it throws an exception.
* struct("d")
* // java.lang.IllegalArgumentException: Field "d" does not exist.
* // java.lang.IllegalArgumentException: d does not exist.
* // ...
*
* // Extract multiple StructFields. Field names are provided in a set.
@ -69,7 +68,7 @@ import org.apache.spark.util.Utils
* // Any names without matching fields will throw an exception.
* // For the case shown below, an exception is thrown due to "d".
* struct(Set("b", "c", "d"))
* // java.lang.IllegalArgumentException: Field "d" does not exist.
* // java.lang.IllegalArgumentException: d does not exist.
* // ...
* }}}
*
@ -272,22 +271,21 @@ case class StructType(fields: Array[StructField]) extends DataType with Seq[Stru
def apply(name: String): StructField = {
nameToField.getOrElse(name,
throw new IllegalArgumentException(
s"""Field "$name" does not exist.
|Available fields: ${fieldNames.mkString(", ")}""".stripMargin))
s"$name does not exist. Available: ${fieldNames.mkString(", ")}"))
}
/**
* Returns a [[StructType]] containing [[StructField]]s of the given names, preserving the
* original order of fields.
*
* @throws IllegalArgumentException if a field cannot be found for any of the given names
* @throws IllegalArgumentException if at least one given field name does not exist
*/
def apply(names: Set[String]): StructType = {
val nonExistFields = names -- fieldNamesSet
if (nonExistFields.nonEmpty) {
throw new IllegalArgumentException(
s"""Nonexistent field(s): ${nonExistFields.mkString(", ")}.
|Available fields: ${fieldNames.mkString(", ")}""".stripMargin)
s"${nonExistFields.mkString(", ")} do(es) not exist. " +
s"Available: ${fieldNames.mkString(", ")}")
}
// Preserve the original order of fields.
StructType(fields.filter(f => names.contains(f.name)))
@ -301,8 +299,7 @@ case class StructType(fields: Array[StructField]) extends DataType with Seq[Stru
def fieldIndex(name: String): Int = {
nameToIndex.getOrElse(name,
throw new IllegalArgumentException(
s"""Field "$name" does not exist.
|Available fields: ${fieldNames.mkString(", ")}""".stripMargin))
s"$name does not exist. Available: ${fieldNames.mkString(", ")}"))
}
private[sql] def getFieldIndex(name: String): Option[Int] = {

View file

@ -22,21 +22,21 @@ import org.apache.spark.sql.types.StructType.fromDDL
class StructTypeSuite extends SparkFunSuite {
val s = StructType.fromDDL("a INT, b STRING")
private val s = StructType.fromDDL("a INT, b STRING")
test("lookup a single missing field should output existing fields") {
val e = intercept[IllegalArgumentException](s("c")).getMessage
assert(e.contains("Available fields: a, b"))
assert(e.contains("Available: a, b"))
}
test("lookup a set of missing fields should output existing fields") {
val e = intercept[IllegalArgumentException](s(Set("a", "c"))).getMessage
assert(e.contains("Available fields: a, b"))
assert(e.contains("Available: a, b"))
}
test("lookup fieldIndex for missing field should output existing fields") {
val e = intercept[IllegalArgumentException](s.fieldIndex("c")).getMessage
assert(e.contains("Available fields: a, b"))
assert(e.contains("Available: a, b"))
}
test("SPARK-24849: toDDL - simple struct") {