This is an automated email from the ASF dual-hosted git repository.

wenchen pushed a commit to branch branch-3.3
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-3.3 by this push:
     new 197c975a676 [SPARK-38972][SQL] Support <param> in error-class messages
197c975a676 is described below

commit 197c975a6765d693f5fafe7614bac6d832c5aabf
Author: Serge Rielau <[email protected]>
AuthorDate: Thu Apr 21 21:53:28 2022 +0800

    [SPARK-38972][SQL] Support <param> in error-class messages
    
    Use symbolic names for parameters in error messages which are substituted 
with %s before formatting the string.
    
    Increase readability of error message docs (TBD)
    
    No
    
    SQL Project.
    
    Closes #36289 from srielau/symbolic-error-arg-names.
    
    Authored-by: Serge Rielau <[email protected]>
    Signed-off-by: Wenchen Fan <[email protected]>
    (cherry picked from commit 43e610333fb78834a09cd82f3da32bad262564f3)
    Signed-off-by: Wenchen Fan <[email protected]>
---
 core/src/main/resources/error/error-classes.json   | 92 +++++++++++-----------
 .../main/scala/org/apache/spark/ErrorInfo.scala    |  3 +-
 2 files changed, 48 insertions(+), 47 deletions(-)

diff --git a/core/src/main/resources/error/error-classes.json 
b/core/src/main/resources/error/error-classes.json
index e1b3c74eec8..283c953ff4f 100644
--- a/core/src/main/resources/error/error-classes.json
+++ b/core/src/main/resources/error/error-classes.json
@@ -1,18 +1,18 @@
 {
   "AMBIGUOUS_FIELD_NAME" : {
-    "message" : [ "Field name %s is ambiguous and has %s matching fields in 
the struct." ],
+    "message" : [ "Field name <fieldName> is ambiguous and has <n> matching 
fields in the struct." ],
     "sqlState" : "42000"
   },
   "ARITHMETIC_OVERFLOW" : {
-    "message" : [ "%s.%s If necessary set %s to false (except for ANSI 
interval type) to bypass this error.%s" ],
+    "message" : [ "<message>.<alternative> If necessary set <config> to false 
(except for ANSI interval type) to bypass this error.<context>" ],
     "sqlState" : "22003"
   },
   "CANNOT_CAST_DATATYPE" : {
-    "message" : [ "Cannot cast %s to %s." ],
+    "message" : [ "Cannot cast <sourceType> to <targetType>." ],
     "sqlState" : "22005"
   },
   "CANNOT_CHANGE_DECIMAL_PRECISION" : {
-    "message" : [ "%s cannot be represented as Decimal(%s, %s). If necessary 
set %s to false to bypass this error.%s" ],
+    "message" : [ "<value> cannot be represented as Decimal(<precision>, 
<scale>). If necessary set <config> to false to bypass this error.<details>" ],
     "sqlState" : "22005"
   },
   "CANNOT_PARSE_DECIMAL" : {
@@ -20,127 +20,127 @@
     "sqlState" : "42000"
   },
   "CANNOT_UP_CAST_DATATYPE" : {
-    "message" : [ "Cannot up cast %s from %s to %s.\n%s" ]
+    "message" : [ "Cannot up cast <value> from <sourceType> to 
<targetType>.\n<details>" ]
   },
   "CANNOT_USE_MIXTURE" : {
     "message" : [ "Cannot use a mixture of aggregate function and group 
aggregate pandas UDF" ]
   },
   "CAST_CAUSES_OVERFLOW" : {
-    "message" : [ "Casting %s to %s causes overflow. To return NULL instead, 
use 'try_cast'. If necessary set %s to false to bypass this error." ],
+    "message" : [ "Casting <value> to <type> causes overflow. To return NULL 
instead, use 'try_cast'. If necessary set <config> to false to bypass this 
error." ],
     "sqlState" : "22005"
   },
   "CONCURRENT_QUERY" : {
     "message" : [ "Another instance of this query was just started by a 
concurrent session." ]
   },
   "DATETIME_OVERFLOW" : {
-    "message" : [ "Datetime operation overflow: %s." ],
+    "message" : [ "Datetime operation overflow: <operation>." ],
     "sqlState" : "22008"
   },
   "DIVIDE_BY_ZERO" : {
-    "message" : [ "divide by zero. To return NULL instead, use 'try_divide'. 
If necessary set %s to false (except for ANSI interval type) to bypass this 
error.%s" ],
+    "message" : [ "divide by zero. To return NULL instead, use 'try_divide'. 
If necessary set <config> to false (except for ANSI interval type) to bypass 
this error.<details>" ],
     "sqlState" : "22012"
   },
   "DUPLICATE_KEY" : {
-    "message" : [ "Found duplicate keys %s" ],
+    "message" : [ "Found duplicate keys <keyColumn>" ],
     "sqlState" : "23000"
   },
   "FAILED_EXECUTE_UDF" : {
-    "message" : [ "Failed to execute user defined function (%s: (%s) => %s)" ]
+    "message" : [ "Failed to execute user defined function (<functionName>: 
(<signature>) => <result>)" ]
   },
   "FAILED_RENAME_PATH" : {
-    "message" : [ "Failed to rename %s to %s as destination already exists" ],
+    "message" : [ "Failed to rename <sourcePath> to <targetPath> as 
destination already exists" ],
     "sqlState" : "22023"
   },
   "FAILED_SET_ORIGINAL_PERMISSION_BACK" : {
-    "message" : [ "Failed to set original permission %s back to the created 
path: %s. Exception: %s" ]
+    "message" : [ "Failed to set original permission <permission> back to the 
created path: <path>. Exception: <message>" ]
   },
   "GRAPHITE_SINK_INVALID_PROTOCOL" : {
-    "message" : [ "Invalid Graphite protocol: %s" ]
+    "message" : [ "Invalid Graphite protocol: <protocol>" ]
   },
   "GRAPHITE_SINK_PROPERTY_MISSING" : {
-    "message" : [ "Graphite sink requires '%s' property." ]
+    "message" : [ "Graphite sink requires '<property>' property." ]
   },
   "GROUPING_COLUMN_MISMATCH" : {
-    "message" : [ "Column of grouping (%s) can't be found in grouping columns 
%s" ],
+    "message" : [ "Column of grouping (<grouping>) can't be found in grouping 
columns <groupingColumns>" ],
     "sqlState" : "42000"
   },
   "GROUPING_ID_COLUMN_MISMATCH" : {
-    "message" : [ "Columns of grouping_id (%s) does not match grouping columns 
(%s)" ],
+    "message" : [ "Columns of grouping_id (<groupingIdColumn>) does not match 
grouping columns (<groupByColumns>)" ],
     "sqlState" : "42000"
   },
   "GROUPING_SIZE_LIMIT_EXCEEDED" : {
-    "message" : [ "Grouping sets size cannot be greater than %s" ]
+    "message" : [ "Grouping sets size cannot be greater than <maxSize>" ]
   },
   "ILLEGAL_SUBSTRING" : {
-    "message" : [ "%s cannot contain %s." ]
+    "message" : [ "<subject> cannot contain <content>." ]
   },
   "INCOMPARABLE_PIVOT_COLUMN" : {
-    "message" : [ "Invalid pivot column '%s'. Pivot columns must be 
comparable." ],
+    "message" : [ "Invalid pivot column '<columnName>'. Pivot columns must be 
comparable." ],
     "sqlState" : "42000"
   },
   "INCOMPATIBLE_DATASOURCE_REGISTER" : {
-    "message" : [ "Detected an incompatible DataSourceRegister. Please remove 
the incompatible library from classpath or upgrade it. Error: %s" ]
+    "message" : [ "Detected an incompatible DataSourceRegister. Please remove 
the incompatible library from classpath or upgrade it. Error: <message>" ]
   },
   "INCONSISTENT_BEHAVIOR_CROSS_VERSION" : {
-    "message" : [ "You may get a different result due to the upgrading to 
Spark >= %s: %s" ]
+    "message" : [ "You may get a different result due to the upgrading to 
Spark >= <sparkVersion>: <details>" ]
   },
   "INDEX_OUT_OF_BOUNDS" : {
-    "message" : [ "Index %s must be between 0 and the length of the 
ArrayData." ],
+    "message" : [ "Index <indexValue> must be between 0 and the length of the 
ArrayData." ],
     "sqlState" : "22023"
   },
   "INTERNAL_ERROR" : {
-    "message" : [ "%s" ]
+    "message" : [ "<message>" ]
   },
   "INVALID_ARRAY_INDEX" : {
-    "message" : [ "Invalid index: %s, numElements: %s. If necessary set %s to 
false to bypass this error." ]
+    "message" : [ "Invalid index: <indexValue>, numElements: <arraySize>. If 
necessary set <config> to false to bypass this error." ]
   },
   "INVALID_ARRAY_INDEX_IN_ELEMENT_AT" : {
-    "message" : [ "Invalid index: %s, numElements: %s. To return NULL instead, 
use 'try_element_at'. If necessary set %s to false to bypass this error." ]
+    "message" : [ "Invalid index: <indexValue>, numElements: <arraySize>. To 
return NULL instead, use 'try_element_at'. If necessary set <config> to false 
to bypass this error." ]
   },
   "INVALID_FIELD_NAME" : {
-    "message" : [ "Field name %s is invalid: %s is not a struct." ],
+    "message" : [ "Field name <fieldName> is invalid: <path> is not a struct." 
],
     "sqlState" : "42000"
   },
   "INVALID_FRACTION_OF_SECOND" : {
-    "message" : [ "The fraction of sec must be zero. Valid range is [0, 60]. 
If necessary set %s to false to bypass this error. " ],
+    "message" : [ "The fraction of sec must be zero. Valid range is [0, 60]. 
If necessary set <config> to false to bypass this error. " ],
     "sqlState" : "22023"
   },
   "INVALID_JSON_SCHEMA_MAPTYPE" : {
-    "message" : [ "Input schema %s can only contain StringType as a key type 
for a MapType." ]
+    "message" : [ "Input schema <dataType> can only contain StringType as a 
key type for a MapType." ]
   },
   "INVALID_PARAMETER_VALUE" : {
-    "message" : [ "The value of parameter(s) '%s' in %s is invalid: %s" ],
+    "message" : [ "The value of parameter(s) '<parameter>' in <functionName> 
is invalid: <expected>" ],
     "sqlState" : "22023"
   },
   "INVALID_SQL_SYNTAX" : {
-    "message" : [ "Invalid SQL syntax: %s" ],
+    "message" : [ "Invalid SQL syntax: <inputString>" ],
     "sqlState" : "42000"
   },
   "INVALID_SYNTAX_FOR_CAST" : {
-    "message" : [ "Invalid input syntax for type %s: %s. To return NULL 
instead, use 'try_cast'. If necessary set %s to false to bypass this error.%s" 
],
+    "message" : [ "Invalid input syntax for type <typeName>: <value>. To 
return NULL instead, use 'try_cast'. If necessary set <config> to false to 
bypass this error.<details>" ],
     "sqlState" : "42000"
   },
   "MAP_KEY_DOES_NOT_EXIST" : {
-    "message" : [ "Key %s does not exist. To return NULL instead, use 
'try_element_at'. If necessary set %s to false to bypass this error.%s" ]
+    "message" : [ "Key <keyValue> does not exist. To return NULL instead, use 
'try_element_at'. If necessary set <config> to false to bypass this 
error.<details>" ]
   },
   "MISSING_COLUMN" : {
-    "message" : [ "Column '%s' does not exist. Did you mean one of the 
following? [%s]" ],
+    "message" : [ "Column '<columnName>' does not exist. Did you mean one of 
the following? [<proposal>]" ],
     "sqlState" : "42000"
   },
   "MISSING_STATIC_PARTITION_COLUMN" : {
-    "message" : [ "Unknown static partition column: %s" ],
+    "message" : [ "Unknown static partition column: <columnName>" ],
     "sqlState" : "42000"
   },
   "NON_LITERAL_PIVOT_VALUES" : {
-    "message" : [ "Literal expressions required for pivot values, found '%s'" 
],
+    "message" : [ "Literal expressions required for pivot values, found 
'<expression>'" ],
     "sqlState" : "42000"
   },
   "NON_PARTITION_COLUMN" : {
-    "message" : [ "PARTITION clause cannot contain a non-partition column 
name: %s" ],
+    "message" : [ "PARTITION clause cannot contain a non-partition column 
name: <columnName>" ],
     "sqlState" : "42000"
   },
   "PARSE_CHAR_MISSING_LENGTH" : {
-    "message" : [ "DataType %s requires a length parameter, for example 
%s(10). Please specify the length." ],
+    "message" : [ "DataType <type> requires a length parameter, for example 
<type>(10). Please specify the length." ],
     "sqlState" : "42000"
   },
   "PARSE_EMPTY_STATEMENT" : {
@@ -148,41 +148,41 @@
     "sqlState" : "42000"
   },
   "PARSE_SYNTAX_ERROR" : {
-    "message" : [ "Syntax error at or near %s%s" ],
+    "message" : [ "Syntax error at or near <error><hint>" ],
     "sqlState" : "42000"
   },
   "PIVOT_VALUE_DATA_TYPE_MISMATCH" : {
-    "message" : [ "Invalid pivot value '%s': value data type %s does not match 
pivot column data type %s" ],
+    "message" : [ "Invalid pivot value '<value>': value data type <valueType> 
does not match pivot column data type <pivotType>" ],
     "sqlState" : "42000"
   },
   "RENAME_SRC_PATH_NOT_FOUND" : {
-    "message" : [ "Failed to rename as %s was not found" ],
+    "message" : [ "Failed to rename as <sourcePath> was not found" ],
     "sqlState" : "22023"
   },
   "SECOND_FUNCTION_ARGUMENT_NOT_INTEGER" : {
-    "message" : [ "The second argument of '%s' function needs to be an 
integer." ],
+    "message" : [ "The second argument of '<functionName>' function needs to 
be an integer." ],
     "sqlState" : "22023"
   },
   "UNABLE_TO_ACQUIRE_MEMORY" : {
-    "message" : [ "Unable to acquire %s bytes of memory, got %s" ]
+    "message" : [ "Unable to acquire <requestedBytes> bytes of memory, got 
<receivedBytes>" ]
   },
   "UNRECOGNIZED_SQL_TYPE" : {
-    "message" : [ "Unrecognized SQL type %s" ],
+    "message" : [ "Unrecognized SQL type <typeName>" ],
     "sqlState" : "42000"
   },
   "UNSUPPORTED_DATATYPE" : {
-    "message" : [ "Unsupported data type %s" ],
+    "message" : [ "Unsupported data type <typeName>" ],
     "sqlState" : "0A000"
   },
   "UNSUPPORTED_FEATURE" : {
-    "message" : [ "The feature is not supported: %s" ],
+    "message" : [ "The feature is not supported: <feature>" ],
     "sqlState" : "0A000"
   },
   "UNSUPPORTED_GROUPING_EXPRESSION" : {
     "message" : [ "grouping()/grouping_id() can only be used with 
GroupingSets/Cube/Rollup" ]
   },
   "UNSUPPORTED_OPERATION" : {
-    "message" : [ "The operation is not supported: %s" ]
+    "message" : [ "The operation is not supported: <operation>" ]
   },
   "WRITING_JOB_ABORTED" : {
     "message" : [ "Writing job aborted" ],
diff --git a/core/src/main/scala/org/apache/spark/ErrorInfo.scala 
b/core/src/main/scala/org/apache/spark/ErrorInfo.scala
index 0917085c01b..6cb8f4d8ed3 100644
--- a/core/src/main/scala/org/apache/spark/ErrorInfo.scala
+++ b/core/src/main/scala/org/apache/spark/ErrorInfo.scala
@@ -58,7 +58,8 @@ private[spark] object SparkThrowableHelper {
   def getMessage(errorClass: String, messageParameters: Array[String]): String 
= {
     val errorInfo = errorClassToInfoMap.getOrElse(errorClass,
       throw new IllegalArgumentException(s"Cannot find error class 
'$errorClass'"))
-    String.format(errorInfo.messageFormat, messageParameters: _*)
+    String.format(errorInfo.messageFormat.replaceAll("<[a-zA-Z0-9_-]+>", "%s"),
+      messageParameters: _*)
   }
 
   def getSqlState(errorClass: String): String = {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to