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]

Reply via email to