This is an automated email from the ASF dual-hosted git repository.
MaxGekk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new 4bd09829483f [SPARK-57756][SQL] Extract SQL UDF default-argument
padding into a SQLFunction helper
4bd09829483f is described below
commit 4bd09829483f86ec3cf3ec04a5cc5a94d03d555c
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]>
---
.../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]