Github user ouyangxiaochen commented on a diff in the pull request:

    https://github.com/apache/spark/pull/17681#discussion_r124183913
  
    --- Diff: 
sql/core/src/main/scala/org/apache/spark/sql/execution/command/functions.scala 
---
    @@ -46,27 +46,53 @@ case class CreateFunctionCommand(
         functionName: String,
         className: String,
         resources: Seq[FunctionResource],
    -    isTemp: Boolean)
    +    isTemp: Boolean,
    +    ifNotExists: Boolean,
    +    replace: Boolean)
       extends RunnableCommand {
     
    +  if (ifNotExists && replace) {
    +    throw new AnalysisException("CREATE FUNCTION with both IF NOT EXISTS 
and REPLACE" +
    +      " is not allowed.")
    +  }
    +
    +  // Disallows 'CREATE TEMPORARY FUNCTION IF NOT EXISTS' to be consistent
    +  // with 'CREATE TEMPORARY FUNCTION'
    +  if (ifNotExists && isTemp) {
    +    throw new AnalysisException(
    +      "It is not allowed to define a TEMPORARY function with IF NOT 
EXISTS.")
    +  }
    +
    +  // Temporary function names should not contain database prefix like 
"database.function"
    +  if (databaseName.isDefined && isTemp) {
    +    throw new AnalysisException(s"Specifying a database in CREATE 
TEMPORARY FUNCTION " +
    +      s"is not allowed: '${databaseName.get}'")
    +  }
    +
       override def run(sparkSession: SparkSession): Seq[Row] = {
         val catalog = sparkSession.sessionState.catalog
    -    val func = CatalogFunction(FunctionIdentifier(functionName, 
databaseName), className, resources)
    +    val func = FunctionIdentifier(functionName, databaseName)
         if (isTemp) {
    -      if (databaseName.isDefined) {
    -        throw new AnalysisException(s"Specifying a database in CREATE 
TEMPORARY FUNCTION " +
    -          s"is not allowed: '${databaseName.get}'")
    -      }
           // We first load resources and then put the builder in the function 
registry.
           // Please note that it is allowed to overwrite an existing temp 
function.
           catalog.loadFunctionResources(resources)
    -      catalog.registerFunction(func, ignoreIfExists = false)
    +      // Handles `CREATE OR REPLACE TEMPORARY FUNCTION AS ... USING ...`
    +      // We drop the temp function in FunctionRegistry firstly and then 
create a new one
    +      if (replace && catalog.functionExists(func)) {
    +        catalog.dropTempFunction(functionName, ignoreIfNotExists = true)
    +      }
    +      catalog.registerFunction(CatalogFunction(func, className, 
resources), ignoreIfExists = false)
         } else {
    -      // For a permanent, we will store the metadata into underlying 
external catalog.
    -      // This function will be loaded into the FunctionRegistry when a 
query uses it.
    -      // We do not load it into FunctionRegistry right now.
    -      // TODO: should we also parse "IF NOT EXISTS"?
    -      catalog.createFunction(func, ignoreIfExists = false)
    +      // Handles `CREATE OR REPLACE FUNCTION AS ... USING ...`
    +      if (replace && catalog.functionExists(func)) {
    +        // alter the function in the metastore
    +        catalog.alterFunction(CatalogFunction(func, className, resources))
    --- End diff --
    
    I added the test case in `SessionCatalogSuite` at line 1230.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to