-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-32677][SQL] Load function resource before create #29502
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9a81c65
ce83487
c75cff4
def8c4e
97dcadf
3e6320d
ba248c9
9fb3c13
fe98b71
8b3a509
fe77698
4750e2e
882942f
d55b8bc
75e61e9
bb6d742
438291b
6584f39
701c25d
3cf971b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1359,16 +1359,24 @@ class SessionCatalog( | |
| val info = new ExpressionInfo(funcDefinition.className, func.database.orNull, func.funcName) | ||
| val builder = | ||
| functionBuilder.getOrElse { | ||
| val className = funcDefinition.className | ||
| if (!Utils.classIsLoadable(className)) { | ||
| throw new AnalysisException(s"Can not load class '$className' when registering " + | ||
| s"the function '$func', please make sure it is on the classpath") | ||
| } | ||
| makeFunctionBuilder(func.unquotedString, className) | ||
| requireFunctionClassExists(funcDefinition) | ||
| makeFunctionBuilder(func.unquotedString, funcDefinition.className) | ||
| } | ||
| functionRegistry.registerFunction(func, info, builder) | ||
| } | ||
|
|
||
| /** | ||
| * Make sure function class is on the classpath. | ||
| */ | ||
| def requireFunctionClassExists(funcDefinition: CatalogFunction): Unit = { | ||
| val className = funcDefinition.className | ||
| if (!Utils.classIsLoadable(className)) { | ||
| throw new AnalysisException(s"Can not load class '$className' when registering " + | ||
| s"the function '${funcDefinition.identifier.unquotedString}', please make sure " + | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. one last thing: shall we fill the default database before putting the function identifier in the error message?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not needed. This method is used by both temporary and permanent function. The temporary has no database name and we can't fill the database name. The permanent follows user created. |
||
| s"it is on the classpath") | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Unregister a temporary or permanent function from a session-specific [[FunctionRegistry]] | ||
| * Return true if function exists. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,7 +42,8 @@ CREATE FUNCTION udaf1 AS 'test.non.existent.udaf' | |
| -- !query schema | ||
| struct<> | ||
| -- !query output | ||
|
|
||
| org.apache.spark.sql.AnalysisException | ||
| Can not load class 'test.non.existent.udaf' when registering the function 'default.udaf1', please make sure it is on the classpath; | ||
|
|
||
|
|
||
| -- !query | ||
|
|
@@ -51,7 +52,7 @@ SELECT default.udaf1(udf(int_col1)) as udaf1, udf(default.udaf1(udf(int_col1))) | |
| struct<> | ||
| -- !query output | ||
| org.apache.spark.sql.AnalysisException | ||
| Can not load class 'test.non.existent.udaf' when registering the function 'default.udaf1', please make sure it is on the classpath; line 1 pos 94 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here it was Do you know why?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For permanent, the old code path is: So the previously msg always contains database name. Now the code path is:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. then shall we fill in the default database when creating permanent functions, to make the error message better?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Permanent function always need a database, it's ok to fill database name when creating. |
||
| Undefined function: 'udaf1'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 1 pos 7 | ||
|
|
||
|
|
||
| -- !query | ||
|
|
@@ -67,4 +68,6 @@ DROP FUNCTION udaf1 | |
| -- !query schema | ||
| struct<> | ||
| -- !query output | ||
| org.apache.spark.sql.catalyst.analysis.NoSuchPermanentFunctionException | ||
| Function 'default.udaf1' not found in database 'default'; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -156,7 +156,9 @@ class HiveUDFDynamicLoadSuite extends QueryTest with SQLTestUtils with TestHiveS | |
|
|
||
| sql(s"CREATE FUNCTION ${udfInfo.funcName} AS '${udfInfo.className}' USING JAR '$jarUrl'") | ||
|
|
||
| assert(Thread.currentThread().getContextClassLoader eq sparkClassLoader) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need load resource during create function.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test was created in #27025. |
||
| assert(Thread.currentThread().getContextClassLoader ne sparkClassLoader) | ||
| assert(Thread.currentThread().getContextClassLoader eq | ||
| spark.sqlContext.sharedState.jarClassLoader) | ||
|
|
||
| // JAR will be loaded at first usage, and it will change the current thread's | ||
| // context classloader to jar classloader in sharedState. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.