srielau commented on code in PR #53570:
URL: https://github.com/apache/spark/pull/53570#discussion_r2867698470


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/resolver/ResolverGuard.scala:
##########
@@ -345,14 +346,56 @@ class ResolverGuard(catalogManager: CatalogManager) 
extends SQLConfHelper {
     createNamedStruct.children.forall(checkExpression)
   }
 
-  private def checkUnresolvedFunction(unresolvedFunction: UnresolvedFunction) =
-    unresolvedFunction.nameParts.size == 1 &&
-    
!ResolverGuard.UNSUPPORTED_FUNCTION_NAMES.contains(unresolvedFunction.nameParts.head)
 &&
-    // UDFs are not supported
-    FunctionRegistry.functionSet.contains(
-      
FunctionIdentifier(unresolvedFunction.nameParts.head.toLowerCase(Locale.ROOT))
-    ) &&
-    unresolvedFunction.children.forall(checkExpression)
+  /**
+   * Checks if an unresolved function is supported by the single-pass analyzer.
+   *
+   * The single-pass analyzer supports built-in functions. For qualified 
function names,
+   * we allow them to pass through to the resolver, which will handle them 
appropriately.
+   * This includes:
+   * - Built-in functions: `builtin.count`, `system.builtin.count`, 
unqualified `count`
+   * - Session/temp functions: `session.my_func`, `system.session.my_func` 
(may or may not work)
+   * - Persistent functions: `catalog.db.func` (not currently supported, but 
not actively blocked)
+   *
+   * We only explicitly reject certain built-in functions that require special 
handling
+   * (lambdas, generators, etc.) via the UNSUPPORTED_FUNCTION_NAMES list.
+   *
+   * @param unresolvedFunction the unresolved function to check
+   * @return true if the function should be allowed to attempt resolution, 
false otherwise
+   */
+  private def checkUnresolvedFunction(unresolvedFunction: UnresolvedFunction) 
= {
+    val nameParts = unresolvedFunction.nameParts
+    val functionName = nameParts.last
+
+    // Only reject functions that are explicitly unsupported or not in the 
builtin registry
+    // for unqualified names. For qualified names, still reject unsupported 
function names
+    // (e.g. builtin.explode), but allow others to pass through for the 
resolver.
+    val shouldReject = if (nameParts.length == 1) {
+      // Unqualified: only allow if it's a known builtin (excluding 
unsupported ones)
+      ResolverGuard.UNSUPPORTED_FUNCTION_NAMES.contains(functionName) ||
+      !FunctionRegistry.functionSet.contains(
+        FunctionIdentifier(functionName.toLowerCase(Locale.ROOT))
+      )
+    } else {
+      // Qualified: reject if the function name is unsupported (e.g. 
builtin.explode);

Review Comment:
   I'm narrowed it as discussed above
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to