This is an automated email from the ASF dual-hosted git repository. maxgekk pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push: new f0d7b31ad61 [SPARK-40965][SQL] Rename the error class `_LEGACY_ERROR_TEMP_1208 ` to `FIELD_NOT_FOUND` f0d7b31ad61 is described below commit f0d7b31ad617d9c112f81eef2130040adbcf454d Author: Max Gekk <max.g...@gmail.com> AuthorDate: Sun Oct 30 12:29:00 2022 +0300 [SPARK-40965][SQL] Rename the error class `_LEGACY_ERROR_TEMP_1208 ` to `FIELD_NOT_FOUND` ### What changes were proposed in this pull request? In the PR, I propose to assign the proper name `FIELD_NOT_FOUND ` to the legacy error class `_LEGACY_ERROR_TEMP_1208 `, and modify test suite to use `checkError()` which checks the error class name, context and etc. ### Why are the changes needed? Proper name improves user experience w/ Spark SQL. ### Does this PR introduce _any_ user-facing change? Yes, the PR changes an user-facing error message. ### How was this patch tested? By running the modified test suites: ``` $ build/sbt "test:testOnly *AnalysisErrorSuite" $ build/sbt "test:testOnly *ResolveSubquerySuite" $ build/sbt "test:testOnly *EncoderResolutionSuite" $ build/sbt "test:testOnly *SQLQuerySuite" ``` Closes #38435 from MaxGekk/field-not-found-error-class. Authored-by: Max Gekk <max.g...@gmail.com> Signed-off-by: Max Gekk <max.g...@gmail.com> --- core/src/main/resources/error/error-classes.json | 10 +- .../spark/sql/errors/QueryCompilationErrors.scala | 6 +- .../sql/catalyst/analysis/AnalysisErrorSuite.scala | 5 +- .../catalyst/analysis/ResolveSubquerySuite.scala | 6 +- .../catalyst/encoders/EncoderResolutionSuite.scala | 10 +- .../expressions/AttributeResolutionSuite.scala | 10 +- .../results/typeCoercion/native/mapZipWith.sql.out | 1 + .../apache/spark/sql/ColumnExpressionSuite.scala | 107 ++++++++++++++------- .../spark/sql/DataFrameSetOperationsSuite.scala | 12 ++- .../scala/org/apache/spark/sql/SQLQuerySuite.scala | 20 ++-- .../spark/sql/execution/SQLViewTestSuite.scala | 12 ++- .../FileMetadataStructRowIndexSuite.scala | 12 ++- .../datasources/FileMetadataStructSuite.scala | 32 +++--- 13 files changed, 154 insertions(+), 89 deletions(-) diff --git a/core/src/main/resources/error/error-classes.json b/core/src/main/resources/error/error-classes.json index 4797ee0d0d0..e45b6e3bdb6 100644 --- a/core/src/main/resources/error/error-classes.json +++ b/core/src/main/resources/error/error-classes.json @@ -356,6 +356,11 @@ ], "sqlState" : "22023" }, + "FIELD_NOT_FOUND" : { + "message" : [ + "No such struct field <fieldName> in <fields>." + ] + }, "FORBIDDEN_OPERATION" : { "message" : [ "The operation <statement> is not allowed on the <objectType>: <objectName>" @@ -2479,11 +2484,6 @@ "The duration and time inputs to window must be an integer, long or string literal." ] }, - "_LEGACY_ERROR_TEMP_1208" : { - "message" : [ - "No such struct field <fieldName> in <fields>." - ] - }, "_LEGACY_ERROR_TEMP_1209" : { "message" : [ "Ambiguous reference to fields <fields>." diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala index cf7e3524d5b..f97888f046b 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryCompilationErrors.scala @@ -2080,10 +2080,10 @@ private[sql] object QueryCompilationErrors extends QueryErrorsBase { def noSuchStructFieldInGivenFieldsError( fieldName: String, fields: Array[StructField]): Throwable = { new AnalysisException( - errorClass = "_LEGACY_ERROR_TEMP_1208", + errorClass = "FIELD_NOT_FOUND", messageParameters = Map( - "fieldName" -> fieldName, - "fields" -> fields.map(_.name).mkString(", "))) + "fieldName" -> toSQLId(fieldName), + "fields" -> fields.map(f => toSQLId(f.name)).mkString(", "))) } def ambiguousReferenceToFieldsError(fields: String): Throwable = { diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala index d530be5f5e4..f3bca030380 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala @@ -370,10 +370,11 @@ class AnalysisErrorSuite extends AnalysisTest { "Ambiguous reference to fields" :: "differentCase" :: "differentcase" :: Nil, caseSensitive = false) - errorTest( + errorClassTest( "missing field", nestedRelation2.select($"top.c"), - "No such struct field" :: "aField" :: "bField" :: "cField" :: Nil, + "FIELD_NOT_FOUND", + Map("fieldName" -> "`c`", "fields" -> "`aField`, `bField`, `cField`"), caseSensitive = false) errorTest( diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/ResolveSubquerySuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/ResolveSubquerySuite.scala index b1d569be5ba..f4e5cf91188 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/ResolveSubquerySuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/ResolveSubquerySuite.scala @@ -173,10 +173,10 @@ class ResolveSubquerySuite extends AnalysisTest { LateralJoin(t4, LateralSubquery(Project(Seq(xa, ya), t0), Seq(x, y)), Inner, None) ) // Analyzer will try to resolve struct first before subquery alias. - assertAnalysisError( + assertAnalysisErrorClass( lateralJoin(t1.as("x"), t4.select($"x.a", $"x.b")), - Seq("No such struct field b in a") - ) + "FIELD_NOT_FOUND", + Map("fieldName" -> "`b`", "fields" -> "`a`")) } test("lateral join with unsupported expressions") { diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/encoders/EncoderResolutionSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/encoders/EncoderResolutionSuite.scala index 5cfbe1f2816..3c967a33ae6 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/encoders/EncoderResolutionSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/encoders/EncoderResolutionSuite.scala @@ -130,8 +130,10 @@ class EncoderResolutionSuite extends PlanTest { test("the real type is not compatible with encoder schema: array element type") { val encoder = ExpressionEncoder[ArrayClass] val attrs = Seq($"arr".array(new StructType().add("c", "int"))) - assert(intercept[AnalysisException](encoder.resolveAndBind(attrs)).message == - "No such struct field a in c.") + checkError( + exception = intercept[AnalysisException](encoder.resolveAndBind(attrs)), + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`a`", "fields" -> "`c`")) } test("the real type is not compatible with encoder schema: nested array element type") { @@ -150,8 +152,8 @@ class EncoderResolutionSuite extends PlanTest { .add("arr", ArrayType(new StructType().add("c", "int"))))) checkError( exception = intercept[AnalysisException](encoder.resolveAndBind(attrs)), - errorClass = "_LEGACY_ERROR_TEMP_1208", - parameters = Map("fieldName" -> "a", "fields" -> "c")) + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`a`", "fields" -> "`c`")) } } diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/AttributeResolutionSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/AttributeResolutionSuite.scala index 813a68f6845..a3885ac77f3 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/AttributeResolutionSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/AttributeResolutionSuite.scala @@ -94,10 +94,12 @@ class AttributeResolutionSuite extends SparkFunSuite { case _ => fail() } - val ex = intercept[AnalysisException] { - attrs.resolve(Seq("ns1", "t", "a", "cc"), resolver) - } - assert(ex.getMessage.contains("No such struct field cc in aa, bb")) + checkError( + exception = intercept[AnalysisException] { + attrs.resolve(Seq("ns1", "t", "a", "cc"), resolver) + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`cc`", "fields" -> "`aa`, `bb`")) } test("attribute resolution with case insensitive resolver") { diff --git a/sql/core/src/test/resources/sql-tests/results/typeCoercion/native/mapZipWith.sql.out b/sql/core/src/test/resources/sql-tests/results/typeCoercion/native/mapZipWith.sql.out index 09c6e10f762..1ce583e9cf9 100644 --- a/sql/core/src/test/resources/sql-tests/results/typeCoercion/native/mapZipWith.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/typeCoercion/native/mapZipWith.sql.out @@ -99,6 +99,7 @@ org.apache.spark.sql.AnalysisException } ] } + -- !query SELECT map_zip_with(decimal_map1, int_map, (k, v1, v2) -> struct(k, v1, v2)) m FROM various_maps diff --git a/sql/core/src/test/scala/org/apache/spark/sql/ColumnExpressionSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/ColumnExpressionSuite.scala index b7f7e96906b..f109b7ff904 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/ColumnExpressionSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/ColumnExpressionSuite.scala @@ -1043,13 +1043,19 @@ class ColumnExpressionSuite extends QueryTest with SharedSparkSession { } test("withField should throw an exception if any intermediate structs don't exist") { - intercept[AnalysisException] { - structLevel2.withColumn("a", $"a".withField("x.b", lit(2))) - }.getMessage should include("No such struct field x in a") + checkError( + exception = intercept[AnalysisException] { + structLevel2.withColumn("a", $"a".withField("x.b", lit(2))) + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`x`", "fields" -> "`a`")) - intercept[AnalysisException] { - structLevel3.withColumn("a", $"a".withField("a.x.b", lit(2))) - }.getMessage should include("No such struct field x in a") + checkError( + exception = intercept[AnalysisException] { + structLevel3.withColumn("a", $"a".withField("a.x.b", lit(2))) + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`x`", "fields" -> "`a`")) } test("withField should throw an exception if intermediate field is not a struct") { @@ -1465,9 +1471,12 @@ class ColumnExpressionSuite extends QueryTest with SharedSparkSession { nullable = false))), nullable = false)))) - intercept[AnalysisException] { - df.withColumn("a", $"a".withField("a.b.e.f", lit(2))) - }.getMessage should include("No such struct field a in a.b") + checkError( + exception = intercept[AnalysisException] { + df.withColumn("a", $"a".withField("a.b.e.f", lit(2))) + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`a`", "fields" -> "`a`.`b`")) } private lazy val mixedCaseStructLevel1: DataFrame = spark.createDataFrame( @@ -1574,13 +1583,19 @@ class ColumnExpressionSuite extends QueryTest with SharedSparkSession { test("withField should throw an exception because casing is different") { withSQLConf(SQLConf.CASE_SENSITIVE.key -> "true") { - intercept[AnalysisException] { - mixedCaseStructLevel2.withColumn("a", $"a".withField("A.a", lit(2))) - }.getMessage should include("No such struct field A in a, B") - - intercept[AnalysisException] { - mixedCaseStructLevel2.withColumn("a", $"a".withField("b.a", lit(2))) - }.getMessage should include("No such struct field b in a, B") + checkError( + exception = intercept[AnalysisException] { + mixedCaseStructLevel2.withColumn("a", $"a".withField("A.a", lit(2))) + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`A`", "fields" -> "`a`, `B`")) + + checkError( + exception = intercept[AnalysisException] { + mixedCaseStructLevel2.withColumn("a", $"a".withField("b.a", lit(2))) + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`b`", "fields" -> "`a`, `B`")) } } @@ -1785,13 +1800,19 @@ class ColumnExpressionSuite extends QueryTest with SharedSparkSession { } test("dropFields should throw an exception if any intermediate structs don't exist") { - intercept[AnalysisException] { - structLevel2.withColumn("a", $"a".dropFields("x.b")) - }.getMessage should include("No such struct field x in a") + checkError( + exception = intercept[AnalysisException] { + structLevel2.withColumn("a", $"a".dropFields("x.b")) + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`x`", "fields" -> "`a`")) - intercept[AnalysisException] { - structLevel3.withColumn("a", $"a".dropFields("a.x.b")) - }.getMessage should include("No such struct field x in a") + checkError( + exception = intercept[AnalysisException] { + structLevel3.withColumn("a", $"a".dropFields("a.x.b")) + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`x`", "fields" -> "`a`")) } test("dropFields should throw an exception if intermediate field is not a struct") { @@ -2035,13 +2056,19 @@ class ColumnExpressionSuite extends QueryTest with SharedSparkSession { test("dropFields should throw an exception because casing is different") { withSQLConf(SQLConf.CASE_SENSITIVE.key -> "true") { - intercept[AnalysisException] { - mixedCaseStructLevel2.withColumn("a", $"a".dropFields("A.a")) - }.getMessage should include("No such struct field A in a, B") - - intercept[AnalysisException] { - mixedCaseStructLevel2.withColumn("a", $"a".dropFields("b.a")) - }.getMessage should include("No such struct field b in a, B") + checkError( + exception = intercept[AnalysisException] { + mixedCaseStructLevel2.withColumn("a", $"a".dropFields("A.a")) + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`A`", "fields" -> "`a`, `B`")) + + checkError( + exception = intercept[AnalysisException] { + mixedCaseStructLevel2.withColumn("a", $"a".dropFields("b.a")) + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`b`", "fields" -> "`a`, `B`")) } } @@ -2279,9 +2306,12 @@ class ColumnExpressionSuite extends QueryTest with SharedSparkSession { } test("should be able to refer to newly added nested column") { - intercept[AnalysisException] { - structLevel1.select($"a".withField("d", lit(4)).withField("e", $"a.d" + 1).as("a")) - }.getMessage should include("No such struct field d in a, b, c") + checkError( + exception = intercept[AnalysisException] { + structLevel1.select($"a".withField("d", lit(4)).withField("e", $"a.d" + 1).as("a")) + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`d`", "fields" -> "`a`, `b`, `c`")) checkAnswer( structLevel1 @@ -2327,11 +2357,14 @@ class ColumnExpressionSuite extends QueryTest with SharedSparkSession { // we can't access the nested column in subsequent select statement after dropping it in a // previous select statement - intercept[AnalysisException]{ - structLevel1 - .select($"a".dropFields("c").as("a")) - .select($"a".withField("z", $"a.c")).as("a") - }.getMessage should include("No such struct field c in a, b") + checkError( + exception = intercept[AnalysisException]{ + structLevel1 + .select($"a".dropFields("c").as("a")) + .select($"a".withField("z", $"a.c")).as("a") + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`c`", "fields" -> "`a`, `b`")) } test("nestedDf should generate nested DataFrames") { diff --git a/sql/core/src/test/scala/org/apache/spark/sql/DataFrameSetOperationsSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/DataFrameSetOperationsSuite.scala index 0acb3842b03..6f3f6237567 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/DataFrameSetOperationsSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/DataFrameSetOperationsSuite.scala @@ -989,15 +989,17 @@ class DataFrameSetOperationsSuite extends QueryTest with SharedSparkSession { // nested struct, inner struct having different col name df1 = Seq((0, UnionClass1a(0, 1L, UnionClass2(1, "2")))).toDF("id", "a") df2 = Seq((1, UnionClass1b(1, 2L, UnionClass3(2, 3L)))).toDF("id", "a") - var errMsg = intercept[AnalysisException] { - df1.unionByName(df2) - }.getMessage - assert(errMsg.contains("No such struct field c in a, b")) + checkError( + exception = intercept[AnalysisException] { + df1.unionByName(df2) + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`c`", "fields" -> "`a`, `b`")) // If right side of the nested struct has extra col. df1 = Seq((1, 2, UnionClass1d(1, 2, Struct3(1)))).toDF("a", "b", "c") df2 = Seq((1, 2, UnionClass1e(1, 2, Struct4(1, 5)))).toDF("a", "b", "c") - errMsg = intercept[AnalysisException] { + val errMsg = intercept[AnalysisException] { df1.unionByName(df2) }.getMessage assert(errMsg.contains("Union can only be performed on tables with" + diff --git a/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala index e9aeba9c820..6f9ffb4a5ff 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala @@ -2994,13 +2994,19 @@ class SQLQuerySuite extends QueryTest with SharedSparkSession with AdaptiveSpark test("SPARK-26402: accessing nested fields with different cases in case insensitive mode") { withSQLConf(SQLConf.CASE_SENSITIVE.key -> "true") { - val msg = intercept[AnalysisException] { - withTable("t") { - sql("create table t (s struct<i: Int>) using json") - checkAnswer(sql("select s.I from t group by s.i"), Nil) - } - }.message - assert(msg.contains("No such struct field I in i")) + checkError( + exception = intercept[AnalysisException] { + withTable("t") { + sql("create table t (s struct<i: Int>) using json") + checkAnswer(sql("select s.I from t group by s.i"), Nil) + } + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`I`", "fields" -> "`i`"), + context = ExpectedContext( + fragment = "s.I", + start = 7, + stop = 9)) } withSQLConf(SQLConf.CASE_SENSITIVE.key -> "false") { diff --git a/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewTestSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewTestSuite.scala index 577d2551c6f..9051d56fd68 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewTestSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/execution/SQLViewTestSuite.scala @@ -334,8 +334,16 @@ abstract class SQLViewTestSuite extends QueryTest with SQLTestUtils { // re-create the table without nested field `i` which is referred by the view. sql("DROP TABLE t") sql("CREATE TABLE t(s STRUCT<j: INT>) USING json") - val e = intercept[AnalysisException](spark.table(viewName)) - assert(e.message.contains("No such struct field i in j")) + checkError( + exception = intercept[AnalysisException](spark.table(viewName)), + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`i`", "fields" -> "`j`"), + context = ExpectedContext( + fragment = "s.i", + objectName = fullyQualifiedViewName("v"), + objectType = "VIEW", + startIndex = 7, + stopIndex = 9)) // drop invalid view should be fine sql(s"DROP VIEW $viewName") diff --git a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/FileMetadataStructRowIndexSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/FileMetadataStructRowIndexSuite.scala index af2d56159bf..61d81125e68 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/FileMetadataStructRowIndexSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/FileMetadataStructRowIndexSuite.scala @@ -122,10 +122,14 @@ class FileMetadataStructRowIndexSuite extends QueryTest with SharedSparkSession test("unsupported file format - read _metadata.row_index") { withReadDataFrame("orc") { df => - val ex = intercept[AnalysisException] { - df.select("*", s"${FileFormat.METADATA_NAME}.${FileFormat.ROW_INDEX}") - } - assert(ex.getMessage.contains("No such struct field row_index")) + checkError( + exception = intercept[AnalysisException] { + df.select("*", s"${FileFormat.METADATA_NAME}.${FileFormat.ROW_INDEX}") + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map( + "fieldName" -> "`row_index`", + "fields" -> "`file_path`, `file_name`, `file_size`, `file_modification_time`")) } } diff --git a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/FileMetadataStructSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/FileMetadataStructSuite.scala index 2c8d72ec609..e0e208b62f1 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/FileMetadataStructSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/FileMetadataStructSuite.scala @@ -223,10 +223,12 @@ class FileMetadataStructSuite extends QueryTest with SharedSparkSession { ) // select metadata will fail when analysis - val ex = intercept[AnalysisException] { - df.select("name", METADATA_FILE_NAME).collect() - } - assert(ex.getMessage.contains("No such struct field file_name in id, university")) + checkError( + exception = intercept[AnalysisException] { + df.select("name", METADATA_FILE_NAME).collect() + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`file_name`", "fields" -> "`id`, `university`")) } metadataColumnsTest("select only metadata", schema) { (df, f0, f1) => @@ -379,15 +381,19 @@ class FileMetadataStructSuite extends QueryTest with SharedSparkSession { ) // select metadata will fail when analysis - metadata cannot overwrite user data - val ex = intercept[AnalysisException] { - df.select("name", "_metadata.file_name").collect() - } - assert(ex.getMessage.contains("No such struct field file_name in id, university")) - - val ex1 = intercept[AnalysisException] { - df.select("name", "_METADATA.file_NAME").collect() - } - assert(ex1.getMessage.contains("No such struct field file_NAME in id, university")) + checkError( + exception = intercept[AnalysisException] { + df.select("name", "_metadata.file_name").collect() + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`file_name`", "fields" -> "`id`, `university`")) + + checkError( + exception = intercept[AnalysisException] { + df.select("name", "_METADATA.file_NAME").collect() + }, + errorClass = "FIELD_NOT_FOUND", + parameters = Map("fieldName" -> "`file_NAME`", "fields" -> "`id`, `university`")) } } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@spark.apache.org For additional commands, e-mail: commits-h...@spark.apache.org