diff --git a/common/utils/src/main/resources/error/error-classes.json b/common/utils/src/main/resources/error/error-classes.json index 53c596c00fc3..417df1ff5b49 100644 --- a/common/utils/src/main/resources/error/error-classes.json +++ b/common/utils/src/main/resources/error/error-classes.json @@ -2210,6 +2210,12 @@ ], "sqlState" : "42607" }, + "NON_FOLDABLE_ARGUMENT" : { + "message" : [ + "The function requires the parameter to be a foldable expression of the type , but the actual argument is a non-foldable." + ], + "sqlState" : "22024" + }, "NON_LAST_MATCHED_CLAUSE_OMIT_CONDITION" : { "message" : [ "When there are more than one MATCHED clauses in a MERGE statement, only the last MATCHED clause can omit the condition." @@ -4024,11 +4030,6 @@ "() doesn't support the mode. Acceptable modes are and ." ] }, - "_LEGACY_ERROR_TEMP_1100" : { - "message" : [ - "The '' parameter of function '' needs to be a literal." - ] - }, "_LEGACY_ERROR_TEMP_1103" : { "message" : [ "Unsupported component type in arrays." diff --git a/docs/sql-error-conditions.md b/docs/sql-error-conditions.md index da802e0ad6a2..f7edab37fe16 100644 --- a/docs/sql-error-conditions.md +++ b/docs/sql-error-conditions.md @@ -1299,6 +1299,12 @@ Cannot call function `` because named argument references are not It is not allowed to use an aggregate function in the argument of another aggregate function. Please use the inner aggregate function in a sub-query. +### NON_FOLDABLE_ARGUMENT + +[SQLSTATE: 22024](sql-error-conditions-sqlstates.html#class-22-data-exception) + +The function `` requires the parameter `` to be a foldable expression of the type ``, but the actual argument is a non-foldable. + ### NON_LAST_MATCHED_CLAUSE_OMIT_CONDITION [SQLSTATE: 42613](sql-error-conditions-sqlstates.html#class-42-syntax-error-or-access-rule-violation) @@ -2174,3 +2180,5 @@ The operation `` requires a ``. But `` is a The `` requires `` parameters but the actual number is ``. For more details see [WRONG_NUM_ARGS](sql-error-conditions-wrong-num-args-error-class.html) + + diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeExpressions.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeExpressions.scala index 51ddf2b85f8c..30a6bec1868b 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeExpressions.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/datetimeExpressions.scala @@ -2934,7 +2934,7 @@ object Extract { } } } else { - throw QueryCompilationErrors.requireLiteralParameter(funcName, "field", "string") + throw QueryCompilationErrors.nonFoldableArgumentError(funcName, "field", StringType) } } } diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala index add59a38b720..89f354db5a97 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala @@ -283,10 +283,10 @@ trait CeilFloorExpressionBuilderBase extends ExpressionBuilder { } else if (numArgs == 2) { val scale = expressions(1) if (!(scale.foldable && scale.dataType == IntegerType)) { - throw QueryCompilationErrors.requireLiteralParameter(funcName, "scale", "int") + throw QueryCompilationErrors.nonFoldableArgumentError(funcName, "scale", IntegerType) } if (scale.eval() == null) { - throw QueryCompilationErrors.requireLiteralParameter(funcName, "scale", "int") + throw QueryCompilationErrors.nonFoldableArgumentError(funcName, "scale", IntegerType) } buildWithTwoParams(expressions(0), scale) } else { diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/numberFormatExpressions.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/numberFormatExpressions.scala index 7875ed8fe20f..38abcc41cbff 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/numberFormatExpressions.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/numberFormatExpressions.scala @@ -247,7 +247,7 @@ object ToCharacterBuilder extends ExpressionBuilder { case _: DatetimeType => DateFormatClass(inputExpr, format) case _: BinaryType => if (!(format.dataType == StringType && format.foldable)) { - throw QueryCompilationErrors.requireLiteralParameter(funcName, "format", "string") + throw QueryCompilationErrors.nonFoldableArgumentError(funcName, "format", StringType) } format.eval().asInstanceOf[UTF8String].toString.toLowerCase(Locale.ROOT).trim match { case "base64" => Base64(inputExpr) 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 e579e5cf565b..a97abf894340 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 @@ -1207,14 +1207,16 @@ private[sql] object QueryCompilationErrors extends QueryErrorsBase with Compilat "failFastMode" -> FailFastMode.name)) } - def requireLiteralParameter( - funcName: String, argName: String, requiredType: String): Throwable = { + def nonFoldableArgumentError( + funcName: String, + paramName: String, + paramType: DataType): Throwable = { new AnalysisException( - errorClass = "_LEGACY_ERROR_TEMP_1100", + errorClass = "NON_FOLDABLE_ARGUMENT", messageParameters = Map( - "argName" -> argName, - "funcName" -> funcName, - "requiredType" -> requiredType)) + "funcName" -> toSQLId(funcName), + "paramName" -> toSQLId(paramName), + "paramType" -> toSQLType(paramType))) } def literalTypeUnsupportedForSourceTypeError(field: String, source: Expression): Throwable = { diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/ceil-floor-with-scale-param.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/ceil-floor-with-scale-param.sql.out index c76b2e5284a4..950584caa816 100644 --- a/sql/core/src/test/resources/sql-tests/analyzer-results/ceil-floor-with-scale-param.sql.out +++ b/sql/core/src/test/resources/sql-tests/analyzer-results/ceil-floor-with-scale-param.sql.out @@ -81,11 +81,12 @@ SELECT CEIL(2.5, null) -- !query analysis org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1100", + "errorClass" : "NON_FOLDABLE_ARGUMENT", + "sqlState" : "22024", "messageParameters" : { - "argName" : "scale", - "funcName" : "ceil", - "requiredType" : "int" + "funcName" : "`ceil`", + "paramName" : "`scale`", + "paramType" : "\"INT\"" }, "queryContext" : [ { "objectType" : "", @@ -102,11 +103,12 @@ SELECT CEIL(2.5, 'a') -- !query analysis org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1100", + "errorClass" : "NON_FOLDABLE_ARGUMENT", + "sqlState" : "22024", "messageParameters" : { - "argName" : "scale", - "funcName" : "ceil", - "requiredType" : "int" + "funcName" : "`ceil`", + "paramName" : "`scale`", + "paramType" : "\"INT\"" }, "queryContext" : [ { "objectType" : "", @@ -223,11 +225,12 @@ SELECT FLOOR(2.5, null) -- !query analysis org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1100", + "errorClass" : "NON_FOLDABLE_ARGUMENT", + "sqlState" : "22024", "messageParameters" : { - "argName" : "scale", - "funcName" : "floor", - "requiredType" : "int" + "funcName" : "`floor`", + "paramName" : "`scale`", + "paramType" : "\"INT\"" }, "queryContext" : [ { "objectType" : "", @@ -244,11 +247,12 @@ SELECT FLOOR(2.5, 'a') -- !query analysis org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1100", + "errorClass" : "NON_FOLDABLE_ARGUMENT", + "sqlState" : "22024", "messageParameters" : { - "argName" : "scale", - "funcName" : "floor", - "requiredType" : "int" + "funcName" : "`floor`", + "paramName" : "`scale`", + "paramType" : "\"INT\"" }, "queryContext" : [ { "objectType" : "", diff --git a/sql/core/src/test/resources/sql-tests/analyzer-results/extract.sql.out b/sql/core/src/test/resources/sql-tests/analyzer-results/extract.sql.out index 6085457deaa0..eabe92ab12de 100644 --- a/sql/core/src/test/resources/sql-tests/analyzer-results/extract.sql.out +++ b/sql/core/src/test/resources/sql-tests/analyzer-results/extract.sql.out @@ -932,11 +932,12 @@ select date_part(c, c) from t -- !query analysis org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1100", + "errorClass" : "NON_FOLDABLE_ARGUMENT", + "sqlState" : "22024", "messageParameters" : { - "argName" : "field", - "funcName" : "date_part", - "requiredType" : "string" + "funcName" : "`date_part`", + "paramName" : "`field`", + "paramType" : "\"STRING\"" }, "queryContext" : [ { "objectType" : "", @@ -964,11 +965,12 @@ select date_part(i, i) from t -- !query analysis org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1100", + "errorClass" : "NON_FOLDABLE_ARGUMENT", + "sqlState" : "22024", "messageParameters" : { - "argName" : "field", - "funcName" : "date_part", - "requiredType" : "string" + "funcName" : "`date_part`", + "paramName" : "`field`", + "paramType" : "\"STRING\"" }, "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 d55e665a2a1e..b15682b0a512 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 @@ -94,11 +94,12 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1100", + "errorClass" : "NON_FOLDABLE_ARGUMENT", + "sqlState" : "22024", "messageParameters" : { - "argName" : "scale", - "funcName" : "ceil", - "requiredType" : "int" + "funcName" : "`ceil`", + "paramName" : "`scale`", + "paramType" : "\"INT\"" }, "queryContext" : [ { "objectType" : "", @@ -117,11 +118,12 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1100", + "errorClass" : "NON_FOLDABLE_ARGUMENT", + "sqlState" : "22024", "messageParameters" : { - "argName" : "scale", - "funcName" : "ceil", - "requiredType" : "int" + "funcName" : "`ceil`", + "paramName" : "`scale`", + "paramType" : "\"INT\"" }, "queryContext" : [ { "objectType" : "", @@ -253,11 +255,12 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1100", + "errorClass" : "NON_FOLDABLE_ARGUMENT", + "sqlState" : "22024", "messageParameters" : { - "argName" : "scale", - "funcName" : "floor", - "requiredType" : "int" + "funcName" : "`floor`", + "paramName" : "`scale`", + "paramType" : "\"INT\"" }, "queryContext" : [ { "objectType" : "", @@ -276,11 +279,12 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1100", + "errorClass" : "NON_FOLDABLE_ARGUMENT", + "sqlState" : "22024", "messageParameters" : { - "argName" : "scale", - "funcName" : "floor", - "requiredType" : "int" + "funcName" : "`floor`", + "paramName" : "`scale`", + "paramType" : "\"INT\"" }, "queryContext" : [ { "objectType" : "", diff --git a/sql/core/src/test/resources/sql-tests/results/extract.sql.out b/sql/core/src/test/resources/sql-tests/results/extract.sql.out index cc6e8bcb36cd..8416327ef315 100644 --- a/sql/core/src/test/resources/sql-tests/results/extract.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/extract.sql.out @@ -714,11 +714,12 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1100", + "errorClass" : "NON_FOLDABLE_ARGUMENT", + "sqlState" : "22024", "messageParameters" : { - "argName" : "field", - "funcName" : "date_part", - "requiredType" : "string" + "funcName" : "`date_part`", + "paramName" : "`field`", + "paramType" : "\"STRING\"" }, "queryContext" : [ { "objectType" : "", @@ -745,11 +746,12 @@ struct<> -- !query output org.apache.spark.sql.AnalysisException { - "errorClass" : "_LEGACY_ERROR_TEMP_1100", + "errorClass" : "NON_FOLDABLE_ARGUMENT", + "sqlState" : "22024", "messageParameters" : { - "argName" : "field", - "funcName" : "date_part", - "requiredType" : "string" + "funcName" : "`date_part`", + "paramName" : "`field`", + "paramType" : "\"STRING\"" }, "queryContext" : [ { "objectType" : "", 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 03b9053c71ab..c61a62f293fa 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 @@ -875,11 +875,11 @@ class StringFunctionsSuite extends QueryTest with SharedSparkSession { exception = intercept[AnalysisException] { df2.select(func(col("input"), col("format"))).collect() }, - errorClass = "_LEGACY_ERROR_TEMP_1100", + errorClass = "NON_FOLDABLE_ARGUMENT", parameters = Map( - "argName" -> "format", - "funcName" -> funcName, - "requiredType" -> "string")) + "funcName" -> s"`$funcName`", + "paramName" -> "`format`", + "paramType" -> "\"STRING\"")) checkError( exception = intercept[AnalysisException] { df2.select(func(col("input"), lit("invalid_format"))).collect()