Skip to content

Commit d736bec

Browse files
panbingkunMaxGekk
authored andcommitted
[SPARK-37939][SQL][3.3] 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 - cannotCleanReservedTablePropertyError => UNSUPPORTED_FEATURE - invalidPropertyKeyForSetQuotedConfigurationError => INVALID_PROPERTY_KEY - invalidPropertyValueForSetQuotedConfigurationError => INVALID_PROPERTY_VALUE - propertiesAndDbPropertiesBothSpecifiedError => UNSUPPORTED_FEATURE This is a backport of #36561. ### 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 #36916 from panbingkun/branch-3.3-SPARK-37939. Authored-by: panbingkun <pbk1982@gmail.com> Signed-off-by: Max Gekk <max.gekk@gmail.com>
1 parent 5d3f336 commit d736bec

File tree

5 files changed

+120
-16
lines changed

5 files changed

+120
-16
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@
113113
"message" : [ "The value of parameter(s) '<parameter>' in <functionName> is invalid: <expected>" ],
114114
"sqlState" : "22023"
115115
},
116+
"INVALID_PROPERTY_KEY" : {
117+
"message" : [ "<key> is an invalid property key, please use quotes, e.g. SET <key>=<value>" ]
118+
},
119+
"INVALID_PROPERTY_VALUE" : {
120+
"message" : [ "<value> is an invalid property value, please use quotes, e.g. SET <key>=<value>" ]
121+
},
116122
"INVALID_SQL_SYNTAX" : {
117123
"message" : [ "Invalid SQL syntax: <inputString>" ],
118124
"sqlState" : "42000"

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

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -260,17 +260,20 @@ private[sql] object QueryParsingErrors extends QueryErrorsBase {
260260
}
261261

262262
def cannotCleanReservedNamespacePropertyError(
263-
property: String, ctx: ParserRuleContext, msg: String): Throwable = {
264-
new ParseException(s"$property is a reserved namespace property, $msg.", ctx)
263+
property: String, ctx: ParserRuleContext, msg: String): ParseException = {
264+
new ParseException("UNSUPPORTED_FEATURE",
265+
Array(s"$property is a reserved namespace property, $msg."), ctx)
265266
}
266267

267-
def propertiesAndDbPropertiesBothSpecifiedError(ctx: CreateNamespaceContext): Throwable = {
268-
new ParseException("Either PROPERTIES or DBPROPERTIES is allowed.", ctx)
268+
def propertiesAndDbPropertiesBothSpecifiedError(ctx: CreateNamespaceContext): ParseException = {
269+
new ParseException("UNSUPPORTED_FEATURE",
270+
Array("set PROPERTIES and DBPROPERTIES at the same time."), ctx)
269271
}
270272

271273
def cannotCleanReservedTablePropertyError(
272-
property: String, ctx: ParserRuleContext, msg: String): Throwable = {
273-
new ParseException(s"$property is a reserved table property, $msg.", ctx)
274+
property: String, ctx: ParserRuleContext, msg: String): ParseException = {
275+
new ParseException("UNSUPPORTED_FEATURE",
276+
Array(s"$property is a reserved table property, $msg."), ctx)
274277
}
275278

276279
def duplicatedTablePathsFoundError(
@@ -367,15 +370,17 @@ private[sql] object QueryParsingErrors extends QueryErrorsBase {
367370
}
368371

369372
def invalidPropertyKeyForSetQuotedConfigurationError(
370-
keyCandidate: String, valueStr: String, ctx: ParserRuleContext): Throwable = {
371-
new ParseException(s"'$keyCandidate' is an invalid property key, please " +
372-
s"use quotes, e.g. SET `$keyCandidate`=`$valueStr`", ctx)
373+
keyCandidate: String, valueStr: String, ctx: ParserRuleContext): ParseException = {
374+
new ParseException(errorClass = "INVALID_PROPERTY_KEY",
375+
messageParameters = Array(toSQLConf(keyCandidate),
376+
toSQLConf(keyCandidate), toSQLConf(valueStr)), ctx)
373377
}
374378

375379
def invalidPropertyValueForSetQuotedConfigurationError(
376-
valueCandidate: String, keyStr: String, ctx: ParserRuleContext): Throwable = {
377-
new ParseException(s"'$valueCandidate' is an invalid property value, please " +
378-
s"use quotes, e.g. SET `$keyStr`=`$valueCandidate`", ctx)
380+
valueCandidate: String, keyStr: String, ctx: ParserRuleContext): ParseException = {
381+
new ParseException(errorClass = "INVALID_PROPERTY_VALUE",
382+
messageParameters = Array(toSQLConf(valueCandidate),
383+
toSQLConf(keyStr), toSQLConf(valueCandidate)), ctx)
379384
}
380385

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

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

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,4 +213,96 @@ class QueryParsingErrorsSuite extends QueryTest with SharedSparkSession {
213213
|--------------------------------------------^^^
214214
|""".stripMargin)
215215
}
216+
217+
test("UNSUPPORTED_FEATURE: cannot set reserved namespace property") {
218+
val sql = "CREATE NAMESPACE IF NOT EXISTS a.b.c WITH PROPERTIES ('location'='/home/user/db')"
219+
val msg = """The feature is not supported: location is a reserved namespace property, """ +
220+
"""please use the LOCATION clause to specify it.(line 1, pos 0)"""
221+
validateParsingError(
222+
sqlText = sql,
223+
errorClass = "UNSUPPORTED_FEATURE",
224+
sqlState = "0A000",
225+
message =
226+
s"""
227+
|$msg
228+
|
229+
|== SQL ==
230+
|$sql
231+
|^^^
232+
|""".stripMargin)
233+
}
234+
235+
test("UNSUPPORTED_FEATURE: cannot set reserved table property") {
236+
val sql = "CREATE TABLE student (id INT, name STRING, age INT) " +
237+
"USING PARQUET TBLPROPERTIES ('provider'='parquet')"
238+
val msg = """The feature is not supported: provider is a reserved table property, """ +
239+
"""please use the USING clause to specify it.(line 1, pos 66)"""
240+
validateParsingError(
241+
sqlText = sql,
242+
errorClass = "UNSUPPORTED_FEATURE",
243+
sqlState = "0A000",
244+
message =
245+
s"""
246+
|$msg
247+
|
248+
|== SQL ==
249+
|$sql
250+
|------------------------------------------------------------------^^^
251+
|""".stripMargin)
252+
}
253+
254+
test("INVALID_PROPERTY_KEY: invalid property key for set quoted configuration") {
255+
val sql = "set =`value`"
256+
val msg = """"" is an invalid property key, please use quotes, """ +
257+
"""e.g. SET ""="value"(line 1, pos 0)"""
258+
validateParsingError(
259+
sqlText = sql,
260+
errorClass = "INVALID_PROPERTY_KEY",
261+
sqlState = null,
262+
message =
263+
s"""
264+
|$msg
265+
|
266+
|== SQL ==
267+
|$sql
268+
|^^^
269+
|""".stripMargin)
270+
}
271+
272+
test("INVALID_PROPERTY_VALUE: invalid property value for set quoted configuration") {
273+
val sql = "set `key`=1;2;;"
274+
val msg = """"1;2;;" is an invalid property value, please use quotes, """ +
275+
"""e.g. SET "key"="1;2;;"(line 1, pos 0)"""
276+
validateParsingError(
277+
sqlText = sql,
278+
errorClass = "INVALID_PROPERTY_VALUE",
279+
sqlState = null,
280+
message =
281+
s"""
282+
|$msg
283+
|
284+
|== SQL ==
285+
|$sql
286+
|^^^
287+
|""".stripMargin)
288+
}
289+
290+
test("UNSUPPORTED_FEATURE: cannot set Properties and DbProperties at the same time") {
291+
val sql = "CREATE NAMESPACE IF NOT EXISTS a.b.c WITH PROPERTIES ('a'='a', 'b'='b', 'c'='c') " +
292+
"WITH DBPROPERTIES('a'='a', 'b'='b', 'c'='c')"
293+
val msg = """The feature is not supported: set PROPERTIES and DBPROPERTIES at the same time.""" +
294+
"""(line 1, pos 0)"""
295+
validateParsingError(
296+
sqlText = sql,
297+
errorClass = "UNSUPPORTED_FEATURE",
298+
sqlState = "0A000",
299+
message =
300+
s"""
301+
|$msg
302+
|
303+
|== SQL ==
304+
|$sql
305+
|^^^
306+
|""".stripMargin)
307+
}
216308
}

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)