Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class ExpressionInfo {
private String usage;
private String name;
private String extended;
private String db;

public String getClassName() {
return className;
Expand All @@ -42,14 +43,23 @@ public String getExtended() {
return extended;
}

public ExpressionInfo(String className, String name, String usage, String extended) {
public String getDb() {
return db;
}

public ExpressionInfo(String className, String db, String name, String usage, String extended) {
this.className = className;
this.db = db;
this.name = name;
this.usage = usage;
this.extended = extended;
}

public ExpressionInfo(String className, String name) {
this(className, name, null, null);
this(className, null, name, null, null);
}

public ExpressionInfo(String className, String db, String name) {
this(className, db, name, null, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ object FunctionRegistry {
val clazz = scala.reflect.classTag[T].runtimeClass
val df = clazz.getAnnotation(classOf[ExpressionDescription])
if (df != null) {
new ExpressionInfo(clazz.getCanonicalName, name, df.usage(), df.extended())
new ExpressionInfo(clazz.getCanonicalName, null, name, df.usage(), df.extended())
} else {
new ExpressionInfo(clazz.getCanonicalName, name)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,10 @@ class SessionCatalog(
requireDbExists(db)
if (externalCatalog.functionExists(db, name.funcName)) {
val metadata = externalCatalog.getFunction(db, name.funcName)
new ExpressionInfo(metadata.className, qualifiedName.unquotedString)
new ExpressionInfo(
metadata.className,
qualifiedName.database.orNull,
qualifiedName.identifier)
} else {
failFunctionLookup(name.funcName)
}
Expand Down Expand Up @@ -1000,7 +1003,10 @@ class SessionCatalog(
// catalog. So, it is possible that qualifiedName is not exactly the same as
// catalogFunction.identifier.unquotedString (difference is on case-sensitivity).
// At here, we preserve the input from the user.
val info = new ExpressionInfo(catalogFunction.className, qualifiedName.unquotedString)
val info = new ExpressionInfo(
catalogFunction.className,
qualifiedName.database.orNull,
qualifiedName.funcName)
val builder = makeFunctionBuilder(qualifiedName.unquotedString, catalogFunction.className)
createTempFunction(qualifiedName.unquotedString, info, builder, ignoreIfExists = false)
// Now, we need to create the Expression.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,15 @@ case class DescribeFunctionCommand(
case _ =>
try {
val info = sparkSession.sessionState.catalog.lookupFunctionInfo(functionName)
val name = if (info.getDb != null) info.getDb + "." + info.getName else info.getName
val result =
Row(s"Function: ${info.getName}") ::
Row(s"Function: $name") ::
Row(s"Class: ${info.getClassName}") ::
Row(s"Usage: ${replaceFunctionName(info.getUsage, info.getName)}") :: Nil

if (isExtended) {
result :+
Row(s"Extended Usage:\n${replaceFunctionName(info.getExtended, info.getName)}")
Row(s"Extended Usage:\n${replaceFunctionName(info.getExtended, name)}")
} else {
result
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ class CatalogImpl(sparkSession: SparkSession) extends Catalog {
private def makeFunction(funcIdent: FunctionIdentifier): Function = {
val metadata = sessionCatalog.lookupFunctionInfo(funcIdent)
new Function(
name = funcIdent.identifier,
database = funcIdent.database.orNull,
name = metadata.getName,
database = metadata.getDb,
description = null, // for now, this is always undefined
className = metadata.getClassName,
isTemporary = funcIdent.database.isEmpty)
isTemporary = metadata.getDb == null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still the right way to do this ? What about global temp tables ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not support global temp functions. So this is the right way to do it.

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,15 +386,24 @@ class CatalogSuite
createFunction("fn2", Some(db))

// Find a temporary function
assert(spark.catalog.getFunction("fn1").name === "fn1")
val fn1 = spark.catalog.getFunction("fn1")
assert(fn1.name === "fn1")
assert(fn1.database === null)
assert(fn1.isTemporary)

// Find a qualified function
assert(spark.catalog.getFunction(db, "fn2").name === "fn2")
val fn2 = spark.catalog.getFunction(db, "fn2")
assert(fn2.name === "fn2")
assert(fn2.database === db)
assert(!fn2.isTemporary)

// Find an unqualified function using the current database
intercept[AnalysisException](spark.catalog.getFunction("fn2"))
spark.catalog.setCurrentDatabase(db)
assert(spark.catalog.getFunction("fn2").name === "fn2")
val unqualified = spark.catalog.getFunction("fn2")
assert(unqualified.name === "fn2")
assert(unqualified.database === db)
assert(!unqualified.isTemporary)
}
}
}
Expand Down