Skip to content

Commit 7309e76

Browse files
panbingkunMaxGekk
authored andcommitted
[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 <pbk1982@gmail.com> Signed-off-by: Max Gekk <max.gekk@gmail.com>
1 parent 3c74aed commit 7309e76

File tree

5 files changed

+129
-11
lines changed

5 files changed

+129
-11
lines changed

core/src/main/resources/error/error-classes.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@
133133
"message" : [ "The value of parameter(s) '<parameter>' in <functionName> is invalid: <expected>" ],
134134
"sqlState" : "22023"
135135
},
136+
"INVALID_PROPERTY_KEY" : {
137+
"message" : [ "<key> is an invalid property key, please use quotes, e.g. SET <key>=<value>" ]
138+
},
139+
"INVALID_PROPERTY_VALUE" : {
140+
"message" : [ "<value> is an invalid property value, please use quotes, e.g. SET <key>=<value>" ]
141+
},
136142
"INVALID_SQL_SYNTAX" : {
137143
"message" : [ "Invalid SQL syntax: <inputString>" ],
138144
"sqlState" : "42000"
@@ -262,6 +268,15 @@
262268
"REPEATED_PIVOT" : {
263269
"message" : [ "Repeated PIVOT operation." ]
264270
},
271+
"SET_NAMESPACE_PROPERTY" : {
272+
"message" : [ "<property> is a reserved namespace property, <msg>." ]
273+
},
274+
"SET_PROPERTIES_AND_DBPROPERTIES" : {
275+
"message" : [ "set PROPERTIES and DBPROPERTIES at the same time." ]
276+
},
277+
"SET_TABLE_PROPERTY" : {
278+
"message" : [ "<property> is a reserved table property, <msg>." ]
279+
},
265280
"TOO_MANY_TYPE_ARGUMENTS_FOR_UDF_CLASS" : {
266281
"message" : [ "UDF class with <n> type arguments." ]
267282
},

sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryParsingErrors.scala

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -267,16 +267,26 @@ object QueryParsingErrors extends QueryErrorsBase {
267267

268268
def cannotCleanReservedNamespacePropertyError(
269269
property: String, ctx: ParserRuleContext, msg: String): Throwable = {
270-
new ParseException(s"$property is a reserved namespace property, $msg.", ctx)
270+
new ParseException(
271+
errorClass = "UNSUPPORTED_FEATURE",
272+
messageParameters = Array("SET_NAMESPACE_PROPERTY", property, msg),
273+
ctx)
271274
}
272275

273276
def propertiesAndDbPropertiesBothSpecifiedError(ctx: CreateNamespaceContext): Throwable = {
274-
new ParseException("Either PROPERTIES or DBPROPERTIES is allowed.", ctx)
277+
new ParseException(
278+
errorClass = "UNSUPPORTED_FEATURE",
279+
messageParameters = Array("SET_PROPERTIES_AND_DBPROPERTIES"),
280+
ctx
281+
)
275282
}
276283

277284
def cannotCleanReservedTablePropertyError(
278285
property: String, ctx: ParserRuleContext, msg: String): Throwable = {
279-
new ParseException(s"$property is a reserved table property, $msg.", ctx)
286+
new ParseException(
287+
errorClass = "UNSUPPORTED_FEATURE",
288+
messageParameters = Array("SET_TABLE_PROPERTY", property, msg),
289+
ctx)
280290
}
281291

282292
def duplicatedTablePathsFoundError(
@@ -378,14 +388,18 @@ object QueryParsingErrors extends QueryErrorsBase {
378388

379389
def invalidPropertyKeyForSetQuotedConfigurationError(
380390
keyCandidate: String, valueStr: String, ctx: ParserRuleContext): Throwable = {
381-
new ParseException(s"'$keyCandidate' is an invalid property key, please " +
382-
s"use quotes, e.g. SET `$keyCandidate`=`$valueStr`", ctx)
391+
new ParseException(errorClass = "INVALID_PROPERTY_KEY",
392+
messageParameters = Array(toSQLConf(keyCandidate),
393+
toSQLConf(keyCandidate), toSQLConf(valueStr)),
394+
ctx)
383395
}
384396

385397
def invalidPropertyValueForSetQuotedConfigurationError(
386398
valueCandidate: String, keyStr: String, ctx: ParserRuleContext): Throwable = {
387-
new ParseException(s"'$valueCandidate' is an invalid property value, please " +
388-
s"use quotes, e.g. SET `$keyStr`=`$valueCandidate`", ctx)
399+
new ParseException(errorClass = "INVALID_PROPERTY_VALUE",
400+
messageParameters = Array(toSQLConf(valueCandidate),
401+
toSQLConf(keyStr), toSQLConf(valueCandidate)),
402+
ctx)
389403
}
390404

391405
def unexpectedFormatForResetConfigurationError(ctx: ResetConfigurationContext): Throwable = {

sql/core/src/test/scala/org/apache/spark/sql/errors/QueryParsingErrorsSuite.scala

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,4 +642,92 @@ class QueryParsingErrorsSuite extends QueryTest with QueryErrorsSuiteBase {
642642
|^^^
643643
|""".stripMargin)
644644
}
645+
646+
test("UNSUPPORTED_FEATURE: cannot set reserved namespace property") {
647+
val sql = "CREATE NAMESPACE IF NOT EXISTS a.b.c WITH PROPERTIES ('location'='/home/user/db')"
648+
validateParsingError(
649+
sqlText = sql,
650+
errorClass = "UNSUPPORTED_FEATURE",
651+
errorSubClass = Some("SET_NAMESPACE_PROPERTY"),
652+
sqlState = "0A000",
653+
message =
654+
"""The feature is not supported: location is a reserved namespace property, """ +
655+
"""please use the LOCATION clause to specify it.(line 1, pos 0)""" +
656+
s"""
657+
|
658+
|== SQL ==
659+
|$sql
660+
|^^^
661+
|""".stripMargin)
662+
}
663+
664+
test("UNSUPPORTED_FEATURE: cannot set reserved table property") {
665+
val sql = "CREATE TABLE student (id INT, name STRING, age INT) " +
666+
"USING PARQUET TBLPROPERTIES ('provider'='parquet')"
667+
validateParsingError(
668+
sqlText = sql,
669+
errorClass = "UNSUPPORTED_FEATURE",
670+
errorSubClass = Some("SET_TABLE_PROPERTY"),
671+
sqlState = "0A000",
672+
message =
673+
"""The feature is not supported: provider is a reserved table property, """ +
674+
"""please use the USING clause to specify it.(line 1, pos 66)""" +
675+
s"""
676+
|
677+
|== SQL ==
678+
|$sql
679+
|------------------------------------------------------------------^^^
680+
|""".stripMargin)
681+
}
682+
683+
test("INVALID_PROPERTY_KEY: invalid property key for set quoted configuration") {
684+
val sql = "set =`value`"
685+
validateParsingError(
686+
sqlText = sql,
687+
errorClass = "INVALID_PROPERTY_KEY",
688+
sqlState = null,
689+
message =
690+
s""""" is an invalid property key, please use quotes, e.g. SET ""="value"(line 1, pos 0)
691+
|
692+
|== SQL ==
693+
|$sql
694+
|^^^
695+
|""".stripMargin)
696+
}
697+
698+
test("INVALID_PROPERTY_VALUE: invalid property value for set quoted configuration") {
699+
val sql = "set `key`=1;2;;"
700+
validateParsingError(
701+
sqlText = sql,
702+
errorClass = "INVALID_PROPERTY_VALUE",
703+
sqlState = null,
704+
message =
705+
""""1;2;;" is an invalid property value, please use quotes, """ +
706+
"""e.g. SET "key"="1;2;;"(line 1, pos 0)""" +
707+
s"""
708+
|
709+
|== SQL ==
710+
|$sql
711+
|^^^
712+
|""".stripMargin)
713+
}
714+
715+
test("UNSUPPORTED_FEATURE: cannot set Properties and DbProperties at the same time") {
716+
val sql = "CREATE NAMESPACE IF NOT EXISTS a.b.c WITH PROPERTIES ('a'='a', 'b'='b', 'c'='c') " +
717+
"WITH DBPROPERTIES('a'='a', 'b'='b', 'c'='c')"
718+
validateParsingError(
719+
sqlText = sql,
720+
errorClass = "UNSUPPORTED_FEATURE",
721+
errorSubClass = Some("SET_PROPERTIES_AND_DBPROPERTIES"),
722+
sqlState = "0A000",
723+
message =
724+
"""The feature is not supported: set PROPERTIES and DBPROPERTIES at the same time.""" +
725+
"""(line 1, pos 0)""" +
726+
s"""
727+
|
728+
|== SQL ==
729+
|$sql
730+
|^^^
731+
|""".stripMargin)
732+
}
645733
}

sql/core/src/test/scala/org/apache/spark/sql/execution/SparkSqlParserSuite.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,11 @@ class SparkSqlParserSuite extends AnalysisTest {
168168
intercept("SET a=1;2;;", expectedErrMsg)
169169

170170
intercept("SET a b=`1;;`",
171-
"'a b' is an invalid property key, please use quotes, e.g. SET `a b`=`1;;`")
171+
"\"a b\" is an invalid property key, please use quotes, e.g. SET \"a b\"=\"1;;\"")
172172

173173
intercept("SET `a`=1;2;;",
174-
"'1;2;;' is an invalid property value, please use quotes, e.g." +
175-
" SET `a`=`1;2;;`")
174+
"\"1;2;;\" is an invalid property value, please use quotes, e.g." +
175+
" SET \"a\"=\"1;2;;\"")
176176
}
177177

178178
test("refresh resource") {

sql/core/src/test/scala/org/apache/spark/sql/execution/command/CreateNamespaceParserSuite.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ class CreateNamespaceParserSuite extends AnalysisTest {
8484
|WITH PROPERTIES ('a'='a', 'b'='b', 'c'='c')
8585
|WITH DBPROPERTIES ('a'='a', 'b'='b', 'c'='c')
8686
""".stripMargin
87-
intercept(sql, "Either PROPERTIES or DBPROPERTIES is allowed")
87+
intercept(sql, "The feature is not supported: " +
88+
"set PROPERTIES and DBPROPERTIES at the same time.")
8889
}
8990

9091
test("create namespace - support for other types in PROPERTIES") {

0 commit comments

Comments
 (0)