This is an automated email from the ASF dual-hosted git repository.
wenchen 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 8fe5bca1773 [SPARK-38957][SQL] Use multipartIdentifier for parsing
table-valued functions
8fe5bca1773 is described below
commit 8fe5bca1773521d967b82a920c6881f081155bc3
Author: allisonwang-db <[email protected]>
AuthorDate: Thu Apr 21 16:19:20 2022 +0800
[SPARK-38957][SQL] Use multipartIdentifier for parsing table-valued
functions
### What changes were proposed in this pull request?
This PR uses multipart identifiers when parsing table-valued functions.
### Why are the changes needed?
To make table-valued functions error messages consistent for 2-part names
and n-part names. For example, before this PR:
```
select * from a.b.c
org.apache.spark.sql.catalyst.parser.ParseException:
Invalid SQL syntax: Unsupported function name `a`.`b`.`c`(line 1, pos 14)
== SQL ==
select * from a.b.c(1)
--------------^^^
```
After this PR:
```
Invalid SQL syntax: table valued function cannot specify database name
(line 1, pos 14)
== SQL ==
SELECT * FROM a.b.c(1)
--------------^^^
```
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
Unit test.
Closes #36272 from allisonwang-db/spark-38957-parse-table-func.
Authored-by: allisonwang-db <[email protected]>
Signed-off-by: Wenchen Fan <[email protected]>
---
.../apache/spark/sql/catalyst/parser/AstBuilder.scala | 19 ++++---------------
.../apache/spark/sql/errors/QueryParsingErrors.scala | 8 ++++++++
.../spark/sql/catalyst/parser/PlanParserSuite.scala | 5 ++++-
.../spark/sql/errors/QueryParsingErrorsSuite.scala | 16 +++++++++++++++-
4 files changed, 31 insertions(+), 17 deletions(-)
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
index f08dccf7fc0..d48924e271e 100644
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
@@ -1307,13 +1307,13 @@ class AstBuilder extends
SqlBaseParserBaseVisitor[AnyRef] with SQLConfHelper wit
} else {
Seq.empty
}
- val name = getFunctionIdentifier(func.functionName)
- if (name.database.nonEmpty) {
- operationNotAllowed(s"table valued function cannot specify database
name: $name", ctx)
+ val name = getFunctionMultiparts(func.functionName)
+ if (name.length > 1) {
+ throw QueryParsingErrors.invalidTableValuedFunctionNameError(name, ctx)
}
val tvf = UnresolvedTableValuedFunction(
- name, func.expression.asScala.map(expression).toSeq, aliases)
+ name.asFunctionIdentifier,
func.expression.asScala.map(expression).toSeq, aliases)
tvf.optionalMap(func.tableAlias.strictIdentifier)(aliasPlan)
}
@@ -1963,17 +1963,6 @@ class AstBuilder extends
SqlBaseParserBaseVisitor[AnyRef] with SQLConfHelper wit
}
}
- /**
- * Get a function identifier consist by database (optional) and name.
- */
- protected def getFunctionIdentifier(ctx: FunctionNameContext):
FunctionIdentifier = {
- if (ctx.qualifiedName != null) {
- visitFunctionName(ctx.qualifiedName)
- } else {
- FunctionIdentifier(ctx.getText, None)
- }
- }
-
protected def getFunctionMultiparts(ctx: FunctionNameContext): Seq[String] =
{
if (ctx.qualifiedName != null) {
ctx.qualifiedName().identifier().asScala.map(_.getText).toSeq
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 0245205cffb..06030fb53f3 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
@@ -469,6 +469,14 @@ object QueryParsingErrors extends QueryErrorsBase {
ctx)
}
+ def invalidTableValuedFunctionNameError(
+ name: Seq[String],
+ ctx: TableValuedFunctionContext): Throwable = {
+ new ParseException(
+ "INVALID_SQL_SYNTAX",
+ Array("table valued function cannot specify database name ",
toSQLId(name)), ctx)
+ }
+
def unclosedBracketedCommentError(command: String, position: Origin):
Throwable = {
new ParseException(Some(command), "Unclosed bracketed comment", position,
position)
}
diff --git
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala
index 1db77f003bf..77fa99b1450 100644
---
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala
+++
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala
@@ -688,7 +688,10 @@ class PlanParserSuite extends AnalysisTest {
UnresolvedTableValuedFunction("range", Literal(2) :: Nil,
Seq.empty).select(star()))
// SPARK-34627
intercept("select * from default.range(2)",
- "table valued function cannot specify database name: default.range")
+ "table valued function cannot specify database name")
+ // SPARK-38957
+ intercept("select * from spark_catalog.default.range(2)",
+ "table valued function cannot specify database name")
}
test("SPARK-20311 range(N) as alias") {
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 8a2911c054a..cb03e507732 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
@@ -215,13 +215,27 @@ class QueryParsingErrorsSuite extends QueryTest with
SharedSparkSession {
}
test("INVALID_SQL_SYNTAX: Invalid table value function name") {
+ validateParsingError(
+ sqlText = "SELECT * FROM db.func()",
+ errorClass = "INVALID_SQL_SYNTAX",
+ sqlState = "42000",
+ message =
+ """
+ |Invalid SQL syntax: table valued function cannot specify database
name (line 1, pos 14)
+ |
+ |== SQL ==
+ |SELECT * FROM db.func()
+ |--------------^^^
+ |""".stripMargin
+ )
+
validateParsingError(
sqlText = "SELECT * FROM ns.db.func()",
errorClass = "INVALID_SQL_SYNTAX",
sqlState = "42000",
message =
"""
- |Invalid SQL syntax: Unsupported function name `ns`.`db`.`func`(line
1, pos 14)
+ |Invalid SQL syntax: table valued function cannot specify database
name (line 1, pos 14)
|
|== SQL ==
|SELECT * FROM ns.db.func()
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]