diff --git a/core/src/main/resources/error/error-classes.json b/core/src/main/resources/error/error-classes.json index 12c97c2108a4..b89565877a4c 100644 --- a/core/src/main/resources/error/error-classes.json +++ b/core/src/main/resources/error/error-classes.json @@ -1468,6 +1468,11 @@ ], "sqlState" : "42000" }, + "WRONG_NUM_ARGS" : { + "message" : [ + "The requires parameters but the actual number is ." + ] + }, "_LEGACY_ERROR_TEMP_0001" : { "message" : [ "Invalid InsertIntoContext" @@ -1950,11 +1955,6 @@ "Undefined function ." ] }, - "_LEGACY_ERROR_TEMP_1042" : { - "message" : [ - "Invalid number of arguments for function . Expected: ; Found: ." - ] - }, "_LEGACY_ERROR_TEMP_1043" : { "message" : [ "Invalid arguments for function ." 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 0f245597efd9..83c4e76f696b 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 @@ -637,13 +637,13 @@ private[sql] object QueryCompilationErrors extends QueryErrorsBase { } def invalidFunctionArgumentsError( - name: String, expectedInfo: String, actualNumber: Int): Throwable = { + name: String, expectedNum: String, actualNum: Int): Throwable = { new AnalysisException( - errorClass = "_LEGACY_ERROR_TEMP_1042", + errorClass = "WRONG_NUM_ARGS", messageParameters = Map( - "name" -> name, - "expectedInfo" -> expectedInfo, - "actualNumber" -> actualNumber.toString)) + "functionName" -> toSQLId(name), + "expectedNum" -> expectedNum, + "actualNum" -> actualNum.toString)) } def invalidFunctionArgumentNumberError( @@ -656,8 +656,7 @@ private[sql] object QueryCompilationErrors extends QueryErrorsBase { val expectedNumberOfParameters = if (validParametersCount.length == 1) { validParametersCount.head.toString } else { - validParametersCount.init.mkString("one of ", ", ", " and ") + - validParametersCount.last + validParametersCount.mkString("[", ", ", "]") } invalidFunctionArgumentsError(name, expectedNumberOfParameters, actualNumber) } diff --git a/sql/core/src/test/resources/sql-tests/results/ansi/string-functions.sql.out b/sql/core/src/test/resources/sql-tests/results/ansi/string-functions.sql.out index 3ab49c14bef1..58727c332b53 100644 --- a/sql/core/src/test/resources/sql-tests/results/ansi/string-functions.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/ansi/string-functions.sql.out @@ -821,11 +821,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "0", - "expectedInfo" : "2", - "name" : "decode" + "actualNum" : "0", + "expectedNum" : "2", + "functionName" : "`decode`" }, "queryContext" : [ { "objectType" : "", @@ -844,11 +844,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "1", - "expectedInfo" : "2", - "name" : "decode" + "actualNum" : "1", + "expectedNum" : "2", + "functionName" : "`decode`" }, "queryContext" : [ { "objectType" : "", diff --git a/sql/core/src/test/resources/sql-tests/results/ceil-floor-with-scale-param.sql.out b/sql/core/src/test/resources/sql-tests/results/ceil-floor-with-scale-param.sql.out index 82ef294d9439..1d8adce90c42 100644 --- a/sql/core/src/test/resources/sql-tests/results/ceil-floor-with-scale-param.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/ceil-floor-with-scale-param.sql.out @@ -140,11 +140,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "3", - "expectedInfo" : "2", - "name" : "ceil" + "actualNum" : "3", + "expectedNum" : "2", + "functionName" : "`ceil`" }, "queryContext" : [ { "objectType" : "", @@ -297,11 +297,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "3", - "expectedInfo" : "2", - "name" : "floor" + "actualNum" : "3", + "expectedNum" : "2", + "functionName" : "`floor`" }, "queryContext" : [ { "objectType" : "", diff --git a/sql/core/src/test/resources/sql-tests/results/csv-functions.sql.out b/sql/core/src/test/resources/sql-tests/results/csv-functions.sql.out index c0df2751933f..c2be9ed7d0ba 100644 --- a/sql/core/src/test/resources/sql-tests/results/csv-functions.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/csv-functions.sql.out @@ -105,11 +105,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "0", - "expectedInfo" : "one of 2 and 3", - "name" : "from_csv" + "actualNum" : "0", + "expectedNum" : "[2, 3]", + "functionName" : "`from_csv`" }, "queryContext" : [ { "objectType" : "", diff --git a/sql/core/src/test/resources/sql-tests/results/json-functions.sql.out b/sql/core/src/test/resources/sql-tests/results/json-functions.sql.out index cb8d4fca4942..3c98cc6e856f 100644 --- a/sql/core/src/test/resources/sql-tests/results/json-functions.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/json-functions.sql.out @@ -109,11 +109,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "0", - "expectedInfo" : "one of 1 and 2", - "name" : "to_json" + "actualNum" : "0", + "expectedNum" : "[1, 2]", + "functionName" : "`to_json`" }, "queryContext" : [ { "objectType" : "", @@ -231,11 +231,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "0", - "expectedInfo" : "one of 2 and 3", - "name" : "from_json" + "actualNum" : "0", + "expectedNum" : "[2, 3]", + "functionName" : "`from_json`" }, "queryContext" : [ { "objectType" : "", @@ -572,11 +572,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "0", - "expectedInfo" : "1", - "name" : "json_array_length" + "actualNum" : "0", + "expectedNum" : "1", + "functionName" : "`json_array_length`" }, "queryContext" : [ { "objectType" : "", @@ -659,11 +659,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "0", - "expectedInfo" : "1", - "name" : "json_object_keys" + "actualNum" : "0", + "expectedNum" : "1", + "functionName" : "`json_object_keys`" }, "queryContext" : [ { "objectType" : "", diff --git a/sql/core/src/test/resources/sql-tests/results/string-functions.sql.out b/sql/core/src/test/resources/sql-tests/results/string-functions.sql.out index 2ea5cefa38d1..c69c23c8b992 100644 --- a/sql/core/src/test/resources/sql-tests/results/string-functions.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/string-functions.sql.out @@ -753,11 +753,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "0", - "expectedInfo" : "2", - "name" : "decode" + "actualNum" : "0", + "expectedNum" : "2", + "functionName" : "`decode`" }, "queryContext" : [ { "objectType" : "", @@ -776,11 +776,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "1", - "expectedInfo" : "2", - "name" : "decode" + "actualNum" : "1", + "expectedNum" : "2", + "functionName" : "`decode`" }, "queryContext" : [ { "objectType" : "", diff --git a/sql/core/src/test/resources/sql-tests/results/table-valued-functions.sql.out b/sql/core/src/test/resources/sql-tests/results/table-valued-functions.sql.out index 4747d36d500f..1e14bfa2a9d6 100644 --- a/sql/core/src/test/resources/sql-tests/results/table-valued-functions.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/table-valued-functions.sql.out @@ -83,7 +83,7 @@ org.apache.spark.sql.AnalysisException "errorClass" : "_LEGACY_ERROR_TEMP_1179", "messageParameters" : { "arguments" : "integer, integer, integer, integer, integer", - "details" : "Invalid number of arguments for function range. Expected: one of 1, 2, 3 and 4; Found: 5.", + "details" : "[WRONG_NUM_ARGS] The `range` requires [1, 2, 3, 4] parameters but the actual number is 5.", "name" : "range", "usage" : "\n range(start: long, end: long, step: long, numSlices: integer)\n range(start: long, end: long, step: long)\n range(start: long, end: long)\n range(end: long)" }, diff --git a/sql/core/src/test/resources/sql-tests/results/timestamp-ntz.sql.out b/sql/core/src/test/resources/sql-tests/results/timestamp-ntz.sql.out index 5a634f39a884..ef47da8c8c7c 100644 --- a/sql/core/src/test/resources/sql-tests/results/timestamp-ntz.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/timestamp-ntz.sql.out @@ -46,11 +46,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "7", - "expectedInfo" : "6", - "name" : "make_timestamp_ntz" + "actualNum" : "7", + "expectedNum" : "6", + "functionName" : "`make_timestamp_ntz`" }, "queryContext" : [ { "objectType" : "", diff --git a/sql/core/src/test/resources/sql-tests/results/udaf/udaf.sql.out b/sql/core/src/test/resources/sql-tests/results/udaf/udaf.sql.out index 90295e40edd5..c8c5bd286d62 100644 --- a/sql/core/src/test/resources/sql-tests/results/udaf/udaf.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/udaf/udaf.sql.out @@ -32,11 +32,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "2", - "expectedInfo" : "1", - "name" : "spark_catalog.default.mydoubleavg" + "actualNum" : "2", + "expectedNum" : "1", + "functionName" : "`spark_catalog`.`default`.`mydoubleavg`" }, "queryContext" : [ { "objectType" : "", diff --git a/sql/core/src/test/resources/sql-tests/results/udf/udf-udaf.sql.out b/sql/core/src/test/resources/sql-tests/results/udf/udf-udaf.sql.out index 6e13a62d4b9d..58389f26ea3c 100644 --- a/sql/core/src/test/resources/sql-tests/results/udf/udf-udaf.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/udf/udf-udaf.sql.out @@ -32,11 +32,11 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1042", + "errorClass" : "WRONG_NUM_ARGS", "messageParameters" : { - "actualNumber" : "2", - "expectedInfo" : "1", - "name" : "spark_catalog.default.mydoubleavg" + "actualNum" : "2", + "expectedNum" : "1", + "functionName" : "`spark_catalog`.`default`.`mydoubleavg`" }, "queryContext" : [ { "objectType" : "", diff --git a/sql/core/src/test/scala/org/apache/spark/sql/DataFrameFunctionsSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/DataFrameFunctionsSuite.scala index 2a15fbc9534b..61f671437f0c 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/DataFrameFunctionsSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/DataFrameFunctionsSuite.scala @@ -28,6 +28,7 @@ import org.apache.spark.SparkException import org.apache.spark.sql.catalyst.InternalRow import org.apache.spark.sql.catalyst.analysis.{FunctionRegistry, UnresolvedAttribute} import org.apache.spark.sql.catalyst.expressions.{Alias, ArraysZip, AttributeReference, Expression, NamedExpression, UnaryExpression} +import org.apache.spark.sql.catalyst.expressions.Cast._ import org.apache.spark.sql.catalyst.expressions.codegen.CodegenFallback import org.apache.spark.sql.catalyst.plans.logical.OneRowRelation import org.apache.spark.sql.catalyst.util.DateTimeTestUtils.{withDefaultTimeZone, UTC} @@ -4847,14 +4848,34 @@ class DataFrameFunctionsSuite extends QueryTest with SharedSparkSession { (Seq.empty, Seq("x", "z"), 3), (null, Seq("x", "z"), 4) ).toDF("a1", "a2", "i") - val ex1 = intercept[AnalysisException] { - df.selectExpr("zip_with(a1, a2, x -> x)") - } - assert(ex1.getMessage.contains("The number of lambda function arguments '1' does not match")) - val ex2 = intercept[AnalysisException] { - df.selectExpr("zip_with(a1, a2, (acc, x) -> x, (acc, x) -> x)") - } - assert(ex2.getMessage.contains("Invalid number of arguments for function zip_with")) + checkError( + exception = intercept[AnalysisException] { + df.selectExpr("zip_with(a1, a2, x -> x)") + }, + errorClass = "_LEGACY_ERROR_TEMP_2300", + parameters = Map( + "namesSize" -> "1", + "argInfoSize" -> "2"), + context = ExpectedContext( + fragment = "x -> x", + start = 17, + stop = 22) + ) + + checkError( + exception = intercept[AnalysisException] { + df.selectExpr("zip_with(a1, a2, (acc, x) -> x, (acc, x) -> x)") + }, + errorClass = "WRONG_NUM_ARGS", + parameters = Map( + "functionName" -> toSQLId("zip_with"), + "expectedNum" -> "3", + "actualNum" -> "4"), + context = ExpectedContext( + fragment = "zip_with(a1, a2, (acc, x) -> x, (acc, x) -> x)", + start = 0, + stop = 45) + ) checkError( exception = intercept[AnalysisException] { 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 cc703035b1ed..ca7c4bfe4ad8 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 @@ -2630,8 +2630,22 @@ class SQLQuerySuite extends QueryTest with SharedSparkSession with AdaptiveSpark } test("RuntimeReplaceable functions should not take extra parameters") { - val e = intercept[AnalysisException](sql("SELECT nvl(1, 2, 3)")) - assert(e.message.contains("Invalid number of arguments")) + checkError( + exception = intercept[AnalysisException] { + sql("SELECT nvl(1, 2, 3)") + }, + errorClass = "WRONG_NUM_ARGS", + parameters = Map( + "functionName" -> toSQLId("nvl"), + "expectedNum" -> "2", + "actualNum" -> "3" + ), + context = ExpectedContext( + start = 7, + stop = 18, + fragment = "nvl(1, 2, 3)" + ) + ) } test("SPARK-21228: InSet incorrect handling of structs") { diff --git a/sql/core/src/test/scala/org/apache/spark/sql/StringFunctionsSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/StringFunctionsSuite.scala index eaa94077bfe8..2372fe6f78db 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/StringFunctionsSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/StringFunctionsSuite.scala @@ -17,11 +17,11 @@ package org.apache.spark.sql +import org.apache.spark.sql.catalyst.expressions.Cast._ import org.apache.spark.sql.functions._ import org.apache.spark.sql.internal.SQLConf import org.apache.spark.sql.test.SharedSparkSession - class StringFunctionsSuite extends QueryTest with SharedSparkSession { import testImplicits._ @@ -575,10 +575,21 @@ class StringFunctionsSuite extends QueryTest with SharedSparkSession { Row(null, Seq(Seq("10")), Seq(Seq("3.14")))) // Argument number exception - val m = intercept[AnalysisException] { - df.selectExpr("sentences()") - }.getMessage - assert(m.contains("Invalid number of arguments for function sentences")) + checkError( + exception = intercept[AnalysisException] { + df.selectExpr("sentences()") + }, + errorClass = "WRONG_NUM_ARGS", + parameters = Map( + "functionName" -> toSQLId("sentences"), + "expectedNum" -> "[1, 2, 3]", + "actualNum" -> "0" + ), + context = ExpectedContext( + fragment = "sentences()", + start = 0, + stop = 10) + ) } test("str_to_map function") { diff --git a/sql/core/src/test/scala/org/apache/spark/sql/UDFSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/UDFSuite.scala index 5c894876be86..d158ace7928e 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/UDFSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/UDFSuite.scala @@ -29,6 +29,7 @@ import org.apache.spark.sql.api.java._ import org.apache.spark.sql.catalyst.FunctionIdentifier import org.apache.spark.sql.catalyst.encoders.{ExpressionEncoder, OuterScopes} import org.apache.spark.sql.catalyst.expressions.{Literal, ScalaUDF} +import org.apache.spark.sql.catalyst.expressions.Cast._ import org.apache.spark.sql.catalyst.plans.logical.Project import org.apache.spark.sql.catalyst.util.DateTimeUtils import org.apache.spark.sql.execution.{QueryExecution, SimpleMode} @@ -100,19 +101,41 @@ class UDFSuite extends QueryTest with SharedSparkSession { test("error reporting for incorrect number of arguments - builtin function") { val df = spark.emptyDataFrame - val e = intercept[AnalysisException] { - df.selectExpr("substr('abcd', 2, 3, 4)") - } - assert(e.getMessage.contains("Invalid number of arguments for function substr. Expected:")) + checkError( + exception = intercept[AnalysisException] { + df.selectExpr("substr('abcd', 2, 3, 4)") + }, + errorClass = "WRONG_NUM_ARGS", + parameters = Map( + "functionName" -> toSQLId("substr"), + "expectedNum" -> "[2, 3]", + "actualNum" -> "4" + ), + context = ExpectedContext( + fragment = "substr('abcd', 2, 3, 4)", + start = 0, + stop = 22) + ) } test("error reporting for incorrect number of arguments - udf") { val df = spark.emptyDataFrame - val e = intercept[AnalysisException] { - spark.udf.register("foo", (_: String).length) - df.selectExpr("foo(2, 3, 4)") - } - assert(e.getMessage.contains("Invalid number of arguments for function foo. Expected:")) + checkError( + exception = intercept[AnalysisException] { + spark.udf.register("foo", (_: String).length) + df.selectExpr("foo(2, 3, 4)") + }, + errorClass = "WRONG_NUM_ARGS", + parameters = Map( + "functionName" -> toSQLId("foo"), + "expectedNum" -> "1", + "actualNum" -> "3" + ), + context = ExpectedContext( + fragment = "foo(2, 3, 4)", + start = 0, + stop = 11) + ) } test("error reporting for undefined functions") { diff --git a/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveUDAFSuite.scala b/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveUDAFSuite.scala index 291268380f1e..d5de8a014327 100644 --- a/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveUDAFSuite.scala +++ b/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveUDAFSuite.scala @@ -29,6 +29,7 @@ import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo import test.org.apache.spark.sql.MyDoubleAvg import org.apache.spark.sql.{AnalysisException, QueryTest, Row} +import org.apache.spark.sql.catalyst.expressions.Cast._ import org.apache.spark.sql.execution.adaptive.AdaptiveSparkPlanHelper import org.apache.spark.sql.execution.aggregate.ObjectHashAggregateExec import org.apache.spark.sql.hive.test.TestHiveSingleton @@ -174,11 +175,11 @@ class HiveUDAFSuite extends QueryTest exception = intercept[AnalysisException] { sql(s"SELECT $functionName(100)") }, - errorClass = "_LEGACY_ERROR_TEMP_1042", + errorClass = "WRONG_NUM_ARGS", parameters = Map( - "name" -> "longProductSum", - "expectedInfo" -> "2", - "actualNumber" -> "1"), + "functionName" -> toSQLId("longProductSum"), + "expectedNum" -> "2", + "actualNum" -> "1"), context = ExpectedContext( fragment = "longProductSum(100)", start = 7,