This is an automated email from the ASF dual-hosted git repository.

MaxGekk pushed a commit to branch branch-4.x
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-4.x by this push:
     new e7569f49a9fc [SPARK-57756][SQL] Extract SQL UDF default-argument 
padding into a SQLFunction helper
e7569f49a9fc is described below

commit e7569f49a9fc2f40f9859a399b437987a8f84d93
Author: daniel-lunin-db <[email protected]>
AuthorDate: Thu Jul 2 11:29:36 2026 +0200

    [SPARK-57756][SQL] Extract SQL UDF default-argument padding into a 
SQLFunction helper
    
    Extract the SQL UDF default-argument padding from 
`SessionCatalog.makeSQLFunctionPlan`
    into a `SQLFunction.padArgumentsWithDefaults` helper. This is a straight 
extraction of the
    scalar builder's existing logic (byte-equivalent to the previous inline 
code);
    `makeSQLTableFunctionPlan` keeps its own padding.
    
    ### What changes were proposed in this pull request?
    
    Extract the logic that pads a SQL function call site's arguments with the 
trailing
    parameters' declared defaults (parsing each default, casting it to the 
parameter type,
    and raising `wrongNumArgsError` when a parameter has no default) from
    `SessionCatalog.makeSQLFunctionPlan` into 
`SQLFunction.padArgumentsWithDefaults`.
    
    ### Why are the changes needed?
    
    The single-pass analyzer's SQL UDF resolution needs the same 
default-argument padding.
    Extracting it into a `SQLFunction` helper (next to `parseDefault`) lets 
that path reuse
    this logic instead of adding another inline copy.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No.
    
    ### How was this patch tested?
    
    Behavior-preserving extraction, covered by existing SQL UDF resolution 
tests; CI compiles
    and runs them.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Anthropic Claude Opus)
    
    Closes #56902 from daniel-lunin-db/SPARK-57756-padding.
    
    Authored-by: daniel-lunin-db <[email protected]>
    Signed-off-by: Max Gekk <[email protected]>
    (cherry picked from commit 4bd09829483f86ec3cf3ec04a5cc5a94d03d555c)
    Signed-off-by: Max Gekk <[email protected]>
---
 .../spark/sql/catalyst/catalog/SQLFunction.scala   | 24 +++++++++++++++++++++-
 .../sql/catalyst/catalog/SessionCatalog.scala      | 13 ++----------
 2 files changed, 25 insertions(+), 12 deletions(-)

diff --git 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/SQLFunction.scala
 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/SQLFunction.scala
index 25ce823337ef..4803b063e732 100644
--- 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/SQLFunction.scala
+++ 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/SQLFunction.scala
@@ -26,9 +26,10 @@ import org.apache.spark.SparkException
 import org.apache.spark.sql.AnalysisException
 import org.apache.spark.sql.catalyst.FunctionIdentifier
 import org.apache.spark.sql.catalyst.catalog.UserDefinedFunction._
-import org.apache.spark.sql.catalyst.expressions.{Expression, ExpressionInfo, 
ScalarSubquery}
+import org.apache.spark.sql.catalyst.expressions.{Cast, Expression, 
ExpressionInfo, ScalarSubquery}
 import org.apache.spark.sql.catalyst.parser.ParserInterface
 import org.apache.spark.sql.catalyst.plans.logical.{LogicalPlan, 
OneRowRelation, Project}
+import org.apache.spark.sql.errors.QueryCompilationErrors
 import org.apache.spark.sql.types.{DataType, ExplicitUTF8BinaryStringType, 
StructType}
 
 /**
@@ -299,6 +300,27 @@ object SQLFunction {
     parser.parseExpression(text)
   }
 
+  /**
+   * Pads `arguments` with the trailing parameters' declared defaults so the 
result aligns
+   * one-to-one with `param`'s fields, parsing each default and casting it to 
the parameter type.
+   * A missing parameter without a default raises 
[[QueryCompilationErrors.wrongNumArgsError]].
+   */
+  def padArgumentsWithDefaults(
+      arguments: Seq[Expression],
+      param: StructType,
+      functionName: String,
+      parser: ParserInterface): Seq[Expression] = {
+    arguments ++ param.takeRight(param.size - arguments.size).map { field =>
+      field.getDefault() match {
+        case Some(default) =>
+          Cast(parseDefault(default, parser), field.dataType)
+        case None =>
+          throw QueryCompilationErrors.wrongNumArgsError(
+            functionName, param.size.toString, arguments.size)
+      }
+    }
+  }
+
   /**
    * This method returns an optional DataType indicating, when present, either 
the return type for
    * scalar user-defined functions, or a StructType indicating the names and 
types of the columns in
diff --git 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/SessionCatalog.scala
 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/SessionCatalog.scala
index ae56a811a158..37e03e2284d2 100644
--- 
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/SessionCatalog.scala
+++ 
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/SessionCatalog.scala
@@ -36,7 +36,7 @@ import org.apache.spark.sql.catalyst._
 import org.apache.spark.sql.catalyst.analysis._
 import org.apache.spark.sql.catalyst.analysis.FunctionRegistry.FunctionBuilder
 import 
org.apache.spark.sql.catalyst.analysis.TableFunctionRegistry.TableFunctionBuilder
-import org.apache.spark.sql.catalyst.catalog.SQLFunction.parseDefault
+import 
org.apache.spark.sql.catalyst.catalog.SQLFunction.{padArgumentsWithDefaults, 
parseDefault}
 import org.apache.spark.sql.catalyst.expressions.{Alias, Attribute, 
AttributeReference, Cast, Expression, ExpressionInfo, LateralSubquery, 
NamedArgumentExpression, NamedExpression, OuterReference, ScalarSubquery, 
UpCast}
 import org.apache.spark.sql.catalyst.expressions.NamedLambdaVariable
 import org.apache.spark.sql.catalyst.expressions.UnresolvedNamedLambdaVariable
@@ -1933,16 +1933,7 @@ class SessionCatalog(
         // function name as a qualifier. E.G.:
         // `create function foo(a int) returns int return foo.a`
         val qualifier = Seq(funcName)
-        val paddedInput = input ++
-          param.takeRight(paramSize - input.size).map { p =>
-            val defaultExpr = p.getDefault()
-            if (defaultExpr.isDefined) {
-              Cast(parseDefault(defaultExpr.get, parser), p.dataType)
-            } else {
-              throw QueryCompilationErrors.wrongNumArgsError(
-                name, paramSize.toString, input.size)
-            }
-          }
+        val paddedInput = padArgumentsWithDefaults(input, param, name, parser)
 
         val funcInputMetadata = new MetadataBuilder()
           
.putBoolean(SessionCatalog.SQL_FUNCTION_PARAMETER_ALIAS_METADATA_KEY, true)


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

Reply via email to