@@ -38,7 +38,7 @@ import org.apache.spark.sql.catalyst.analysis._
3838import org .apache .spark .sql .catalyst .analysis .FunctionRegistry .FunctionBuilder
3939import org .apache .spark .sql .catalyst .analysis .TableFunctionRegistry .TableFunctionBuilder
4040import org .apache .spark .sql .catalyst .catalog .SQLFunction .parseDefault
41- import org .apache .spark .sql .catalyst .expressions .{Alias , Attribute , AttributeReference , Cast , Expression , ExpressionInfo , LateralSubquery , NamedArgumentExpression , NamedExpression , OuterReference , ScalarSubquery , UpCast }
41+ import org .apache .spark .sql .catalyst .expressions .{Alias , Attribute , AttributeReference , Cast , Expression , ExpressionInfo , LateralSubquery , NamedArgumentExpression , NamedExpression , NamedLambdaVariable , OuterReference , ScalarSubquery , UnresolvedNamedLambdaVariable , UpCast }
4242import org .apache .spark .sql .catalyst .parser .{CatalystSqlParser , ParserInterface }
4343import org .apache .spark .sql .catalyst .plans .Inner
4444import org .apache .spark .sql .catalyst .plans .logical .{FunctionSignature , InputParameter , LateralJoin , LogicalPlan , NamedParametersSupport , OneRowRelation , Project , SubqueryAlias , View }
@@ -1633,6 +1633,24 @@ class SessionCatalog(
16331633 throw UserDefinedFunctionErrors .notAScalarFunction(function.name.nameParts)
16341634 }
16351635 (input : Seq [Expression ]) => {
1636+ // Check if any input contains a lambda variable - SQL functions cannot be used
1637+ // inside lambda functions in higher-order functions
1638+ val lambdaVar = input.flatMap(_.find {
1639+ case _ : NamedLambdaVariable | _ : UnresolvedNamedLambdaVariable => true
1640+ case _ => false
1641+ }).headOption
1642+ if (lambdaVar.isDefined) {
1643+ // Format input expressions, replacing lambda variables with "lambda <name>" format
1644+ val formattedInputs = input.map {
1645+ case v : NamedLambdaVariable => s " lambda ${v.name}"
1646+ case v : UnresolvedNamedLambdaVariable => s " lambda ${v.name}"
1647+ case e => e.sql
1648+ }.mkString(" , " )
1649+ throw new AnalysisException (
1650+ errorClass = " UNSUPPORTED_FEATURE.LAMBDA_FUNCTION_WITH_SQL_UDF" ,
1651+ messageParameters = Map (
1652+ " funcName" -> s " \" ${function.name.unquotedString}( $formattedInputs) \" " ))
1653+ }
16361654 val args = rearrangeArguments(function.inputParam, input, function.name.toString)
16371655 val returnType = function.getScalarFuncReturnType
16381656 SQLFunctionExpression (
@@ -1712,6 +1730,25 @@ class SessionCatalog(
17121730 name, paramSize.toString, input.size)
17131731 }
17141732
1733+ // Check if any input contains a lambda variable - SQL functions cannot be used
1734+ // inside lambda functions in higher-order functions
1735+ val lambdaVar = input.flatMap(_.find {
1736+ case _ : NamedLambdaVariable | _ : UnresolvedNamedLambdaVariable => true
1737+ case _ => false
1738+ }).headOption
1739+ if (lambdaVar.isDefined) {
1740+ // Format input expressions, replacing lambda variables with "lambda <name>" format
1741+ val formattedInputs = input.map {
1742+ case v : NamedLambdaVariable => s " lambda ${v.name}"
1743+ case v : UnresolvedNamedLambdaVariable => s " lambda ${v.name}"
1744+ case e => e.sql
1745+ }.mkString(" , " )
1746+ throw new AnalysisException (
1747+ errorClass = " UNSUPPORTED_FEATURE.LAMBDA_FUNCTION_WITH_SQL_UDF" ,
1748+ messageParameters = Map (
1749+ " funcName" -> s " \" ${function.name.unquotedString}( $formattedInputs) \" " ))
1750+ }
1751+
17151752 val inputs = inputParam.map { param =>
17161753 // Attributes referencing the input parameters inside the function can use the
17171754 // function name as a qualifier. E.G.:
0 commit comments