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 7309e76d8b9 [SPARK-37939][SQL] Use error classes in the parsing errors 
of properties
7309e76d8b9 is described below

commit 7309e76d8b95e306d6f3d2f611316b748949e9cf
Author: panbingkun <pbk1...@gmail.com>
AuthorDate: Thu May 19 11:29:37 2022 +0300

    [SPARK-37939][SQL] Use error classes in the parsing errors of properties
    
    ## What changes were proposed in this pull request?
    Migrate the following errors in QueryParsingErrors onto use error classes:
    
    - cannotCleanReservedNamespacePropertyError =>
    UNSUPPORTED_FEATURE.SET_NAMESPACE_PROPERTY
    - cannotCleanReservedTablePropertyError => 
UNSUPPORTED_FEATURE.SET_TABLE_PROPERTY
    - invalidPropertyKeyForSetQuotedConfigurationError => INVALID_PROPERTY_KEY
    - invalidPropertyValueForSetQuotedConfigurationError => 
INVALID_PROPERTY_VALUE
    - propertiesAndDbPropertiesBothSpecifiedError => 
UNSUPPORTED_FEATURE.SET_PROPERTIES_AND_DBPROPERTIES
    
    ### Why are the changes needed?
    Porting parsing errors of partitions to new error framework, improve test 
coverage, and document expected error messages in tests.
    
    ### Does this PR introduce any user-facing change?
    No
    
    ### How was this patch tested?
    By running new test:
    ```
    $ build/sbt "sql/testOnly *QueryParsingErrorsSuite*"
    ```
    
    Closes #36561 from panbingkun/SPARK-37939.
    
    Authored-by: panbingkun <pbk1...@gmail.com>
    Signed-off-by: Max Gekk <max.g...@gmail.com>
---
 core/src/main/resources/error/error-classes.json   | 15 ++++
 .../spark/sql/errors/QueryParsingErrors.scala      | 28 +++++--
 .../spark/sql/errors/QueryParsingErrorsSuite.scala | 88 ++++++++++++++++++++++
 .../spark/sql/execution/SparkSqlParserSuite.scala  |  6 +-
 .../command/CreateNamespaceParserSuite.scala       |  3 +-
 5 files changed, 129 insertions(+), 11 deletions(-)

diff --git a/core/src/main/resources/error/error-classes.json 
b/core/src/main/resources/error/error-classes.json
index 21fde82adbb..e4ee09ea8a7 100644
--- a/core/src/main/resources/error/error-classes.json
+++ b/core/src/main/resources/error/error-classes.json
@@ -133,6 +133,12 @@
     "message" : [ "The value of parameter(s) '<parameter>' in <functionName> 
is invalid: <expected>" ],
     "sqlState" : "22023"
   },
+  "INVALID_PROPERTY_KEY" : {
+    "message" : [ "<key> is an invalid property key, please use quotes, e.g. 
SET <key>=<value>" ]
+  },
+  "INVALID_PROPERTY_VALUE" : {
+    "message" : [ "<value> is an invalid property value, please use quotes, 
e.g. SET <key>=<value>" ]
+  },
   "INVALID_SQL_SYNTAX" : {
     "message" : [ "Invalid SQL syntax: <inputString>" ],
     "sqlState" : "42000"
@@ -262,6 +268,15 @@
       "REPEATED_PIVOT" : {
         "message" : [ "Repeated PIVOT operation." ]
       },
+      "SET_NAMESPACE_PROPERTY" : {
+        "message" : [ "<property> is a reserved namespace property, <msg>." ]
+      },
+      "SET_PROPERTIES_AND_DBPROPERTIES" : {
+        "message" : [ "set PROPERTIES and DBPROPERTIES at the same time." ]
+      },
+      "SET_TABLE_PROPERTY" : {
+        "message" : [ "<property> is a reserved table property, <msg>." ]
+      },
       "TOO_MANY_TYPE_ARGUMENTS_FOR_UDF_CLASS" : {
         "message" : [ "UDF class with <n> type arguments." ]
       },
diff --git 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryParsingErrors.scala
 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryParsingErrors.scala
index debfe1b0891..8fa28c0d347 100644
--- 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryParsingErrors.scala
+++ 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryParsingErrors.scala
@@ -267,16 +267,26 @@ object QueryParsingErrors extends QueryErrorsBase {
 
   def cannotCleanReservedNamespacePropertyError(
       property: String, ctx: ParserRuleContext, msg: String): Throwable = {
-    new ParseException(s"$property is a reserved namespace property, $msg.", 
ctx)
+    new ParseException(
+      errorClass = "UNSUPPORTED_FEATURE",
+      messageParameters = Array("SET_NAMESPACE_PROPERTY", property, msg),
+      ctx)
   }
 
   def propertiesAndDbPropertiesBothSpecifiedError(ctx: 
CreateNamespaceContext): Throwable = {
-    new ParseException("Either PROPERTIES or DBPROPERTIES is allowed.", ctx)
+    new ParseException(
+      errorClass = "UNSUPPORTED_FEATURE",
+      messageParameters = Array("SET_PROPERTIES_AND_DBPROPERTIES"),
+      ctx
+    )
   }
 
   def cannotCleanReservedTablePropertyError(
       property: String, ctx: ParserRuleContext, msg: String): Throwable = {
-    new ParseException(s"$property is a reserved table property, $msg.", ctx)
+    new ParseException(
+      errorClass = "UNSUPPORTED_FEATURE",
+      messageParameters = Array("SET_TABLE_PROPERTY", property, msg),
+      ctx)
   }
 
   def duplicatedTablePathsFoundError(
@@ -378,14 +388,18 @@ object QueryParsingErrors extends QueryErrorsBase {
 
   def invalidPropertyKeyForSetQuotedConfigurationError(
       keyCandidate: String, valueStr: String, ctx: ParserRuleContext): 
Throwable = {
-    new ParseException(s"'$keyCandidate' is an invalid property key, please " +
-      s"use quotes, e.g. SET `$keyCandidate`=`$valueStr`", ctx)
+    new ParseException(errorClass = "INVALID_PROPERTY_KEY",
+      messageParameters = Array(toSQLConf(keyCandidate),
+        toSQLConf(keyCandidate), toSQLConf(valueStr)),
+      ctx)
   }
 
   def invalidPropertyValueForSetQuotedConfigurationError(
       valueCandidate: String, keyStr: String, ctx: ParserRuleContext): 
Throwable = {
-    new ParseException(s"'$valueCandidate' is an invalid property value, 
please " +
-      s"use quotes, e.g. SET `$keyStr`=`$valueCandidate`", ctx)
+    new ParseException(errorClass = "INVALID_PROPERTY_VALUE",
+      messageParameters = Array(toSQLConf(valueCandidate),
+        toSQLConf(keyStr), toSQLConf(valueCandidate)),
+      ctx)
   }
 
   def unexpectedFormatForResetConfigurationError(ctx: 
ResetConfigurationContext): Throwable = {
diff --git 
a/sql/core/src/test/scala/org/apache/spark/sql/errors/QueryParsingErrorsSuite.scala
 
b/sql/core/src/test/scala/org/apache/spark/sql/errors/QueryParsingErrorsSuite.scala
index 50966db2a21..6dc40c3eadb 100644
--- 
a/sql/core/src/test/scala/org/apache/spark/sql/errors/QueryParsingErrorsSuite.scala
+++ 
b/sql/core/src/test/scala/org/apache/spark/sql/errors/QueryParsingErrorsSuite.scala
@@ -642,4 +642,92 @@ class QueryParsingErrorsSuite extends QueryTest with 
QueryErrorsSuiteBase {
           |^^^
           |""".stripMargin)
   }
+
+  test("UNSUPPORTED_FEATURE: cannot set reserved namespace property") {
+    val sql = "CREATE NAMESPACE IF NOT EXISTS a.b.c WITH PROPERTIES 
('location'='/home/user/db')"
+    validateParsingError(
+      sqlText = sql,
+      errorClass = "UNSUPPORTED_FEATURE",
+      errorSubClass = Some("SET_NAMESPACE_PROPERTY"),
+      sqlState = "0A000",
+      message =
+        """The feature is not supported: location is a reserved namespace 
property, """ +
+        """please use the LOCATION clause to specify it.(line 1, pos 0)""" +
+        s"""
+          |
+          |== SQL ==
+          |$sql
+          |^^^
+          |""".stripMargin)
+  }
+
+  test("UNSUPPORTED_FEATURE: cannot set reserved table property") {
+    val sql = "CREATE TABLE student (id INT, name STRING, age INT) " +
+      "USING PARQUET TBLPROPERTIES ('provider'='parquet')"
+    validateParsingError(
+      sqlText = sql,
+      errorClass = "UNSUPPORTED_FEATURE",
+      errorSubClass = Some("SET_TABLE_PROPERTY"),
+      sqlState = "0A000",
+      message =
+        """The feature is not supported: provider is a reserved table 
property, """ +
+        """please use the USING clause to specify it.(line 1, pos 66)""" +
+        s"""
+          |
+          |== SQL ==
+          |$sql
+          
|------------------------------------------------------------------^^^
+          |""".stripMargin)
+  }
+
+  test("INVALID_PROPERTY_KEY: invalid property key for set quoted 
configuration") {
+    val sql = "set =`value`"
+    validateParsingError(
+      sqlText = sql,
+      errorClass = "INVALID_PROPERTY_KEY",
+      sqlState = null,
+      message =
+        s""""" is an invalid property key, please use quotes, e.g. SET 
""="value"(line 1, pos 0)
+          |
+          |== SQL ==
+          |$sql
+          |^^^
+          |""".stripMargin)
+  }
+
+  test("INVALID_PROPERTY_VALUE: invalid property value for set quoted 
configuration") {
+    val sql = "set `key`=1;2;;"
+    validateParsingError(
+      sqlText = sql,
+      errorClass = "INVALID_PROPERTY_VALUE",
+      sqlState = null,
+      message =
+        """"1;2;;" is an invalid property value, please use quotes, """ +
+        """e.g. SET "key"="1;2;;"(line 1, pos 0)""" +
+        s"""
+           |
+           |== SQL ==
+           |$sql
+           |^^^
+           |""".stripMargin)
+  }
+
+  test("UNSUPPORTED_FEATURE: cannot set Properties and DbProperties at the 
same time") {
+    val sql = "CREATE NAMESPACE IF NOT EXISTS a.b.c WITH PROPERTIES ('a'='a', 
'b'='b', 'c'='c') " +
+      "WITH DBPROPERTIES('a'='a', 'b'='b', 'c'='c')"
+    validateParsingError(
+      sqlText = sql,
+      errorClass = "UNSUPPORTED_FEATURE",
+      errorSubClass = Some("SET_PROPERTIES_AND_DBPROPERTIES"),
+      sqlState = "0A000",
+      message =
+        """The feature is not supported: set PROPERTIES and DBPROPERTIES at 
the same time.""" +
+        """(line 1, pos 0)""" +
+        s"""
+          |
+          |== SQL ==
+          |$sql
+          |^^^
+          |""".stripMargin)
+  }
 }
diff --git 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/SparkSqlParserSuite.scala
 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/SparkSqlParserSuite.scala
index 8f6dd04790b..c70c80dee51 100644
--- 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/SparkSqlParserSuite.scala
+++ 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/SparkSqlParserSuite.scala
@@ -168,11 +168,11 @@ class SparkSqlParserSuite extends AnalysisTest {
     intercept("SET a=1;2;;", expectedErrMsg)
 
     intercept("SET a b=`1;;`",
-      "'a b' is an invalid property key, please use quotes, e.g. SET `a 
b`=`1;;`")
+      "\"a b\" is an invalid property key, please use quotes, e.g. SET \"a 
b\"=\"1;;\"")
 
     intercept("SET `a`=1;2;;",
-      "'1;2;;' is an invalid property value, please use quotes, e.g." +
-        " SET `a`=`1;2;;`")
+      "\"1;2;;\" is an invalid property value, please use quotes, e.g." +
+        " SET \"a\"=\"1;2;;\"")
   }
 
   test("refresh resource") {
diff --git 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/command/CreateNamespaceParserSuite.scala
 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/command/CreateNamespaceParserSuite.scala
index 69a208b9424..6c59512148a 100644
--- 
a/sql/core/src/test/scala/org/apache/spark/sql/execution/command/CreateNamespaceParserSuite.scala
+++ 
b/sql/core/src/test/scala/org/apache/spark/sql/execution/command/CreateNamespaceParserSuite.scala
@@ -84,7 +84,8 @@ class CreateNamespaceParserSuite extends AnalysisTest {
          |WITH PROPERTIES ('a'='a', 'b'='b', 'c'='c')
          |WITH DBPROPERTIES ('a'='a', 'b'='b', 'c'='c')
       """.stripMargin
-    intercept(sql, "Either PROPERTIES or DBPROPERTIES is allowed")
+    intercept(sql, "The feature is not supported: " +
+      "set PROPERTIES and DBPROPERTIES at the same time.")
   }
 
   test("create namespace - support for other types in PROPERTIES") {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@spark.apache.org
For additional commands, e-mail: commits-h...@spark.apache.org

Reply via email to