diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala index f31354179674e..b1eaec8bb5214 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala @@ -2650,18 +2650,23 @@ class Analyzer( // unresolved. !f.inputs.exists(_.containsPattern(LATERAL_COLUMN_ALIAS_REFERENCE)) => withPosition(f) { - val plan = resolve(f) - // Extract the function input project list from the SQL function plan and - // inline the SQL function expression. - plan match { - case Project(body :: Nil, Project(aliases, _: OneRowRelation)) => - val inputs = aliases.map(stripOuterReference) - projectList ++= inputs - SQLScalarFunction(f.function, inputs.map(_.toAttribute), body) - case o => - throw new AnalysisException( - errorClass = "INVALID_SQL_FUNCTION_PLAN_STRUCTURE", - messageParameters = Map("plan" -> o.toString)) + // Set CurrentOrigin to the SQL function call site so that input-binding + // Casts constructed inside makeSQLFunctionPlan capture the call-site + // position in their queryContext snapshot (see Cast.initQueryContext). + withOrigin(f.origin) { + val plan = resolve(f) + // Extract the function input project list from the SQL function plan and + // inline the SQL function expression. + plan match { + case Project(body :: Nil, Project(aliases, _: OneRowRelation)) => + val inputs = aliases.map(stripOuterReference) + projectList ++= inputs + SQLScalarFunction(f.function, inputs.map(_.toAttribute), body) + case o => + throw new AnalysisException( + errorClass = "INVALID_SQL_FUNCTION_PLAN_STRUCTURE", + messageParameters = Map("plan" -> o.toString)) + } } } case o => o.mapChildren(rewriteSQLFunctions(_, projectList)) diff --git a/sql/core/src/test/resources/sql-tests/results/sql-udf.sql.out b/sql/core/src/test/resources/sql-tests/results/sql-udf.sql.out index a5e7965c10f40..b227fd3c9475c 100644 --- a/sql/core/src/test/resources/sql-tests/results/sql-udf.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/sql-udf.sql.out @@ -823,7 +823,9 @@ org.apache.spark.SparkException "queryContext" : [ { "objectType" : "", "objectName" : "", - "fragment" : "" + "startIndex" : 8, + "stopIndex" : 14, + "fragment" : "foo51()" } ] } @@ -956,7 +958,9 @@ org.apache.spark.SparkRuntimeException "queryContext" : [ { "objectType" : "", "objectName" : "", - "fragment" : "" + "startIndex" : 8, + "stopIndex" : 24, + "fragment" : "foo9a('Nonsense')" } ] } @@ -1209,7 +1213,9 @@ org.apache.spark.SparkArithmeticException "queryContext" : [ { "objectType" : "", "objectName" : "", - "fragment" : "" + "startIndex" : 8, + "stopIndex" : 17, + "fragment" : "foo9f(999)" } ] } @@ -1232,7 +1238,9 @@ org.apache.spark.SparkArithmeticException "queryContext" : [ { "objectType" : "", "objectName" : "", - "fragment" : "" + "startIndex" : 8, + "stopIndex" : 21, + "fragment" : "foo9f(999 + 1)" } ] } @@ -1271,7 +1279,9 @@ org.apache.spark.SparkNumberFormatException "queryContext" : [ { "objectType" : "", "objectName" : "", - "fragment" : "" + "startIndex" : 8, + "stopIndex" : 26, + "fragment" : "foo9g('hello', '7')" } ] } @@ -1294,7 +1304,9 @@ org.apache.spark.SparkNumberFormatException "queryContext" : [ { "objectType" : "", "objectName" : "", - "fragment" : "" + "startIndex" : 8, + "stopIndex" : 25, + "fragment" : "foo9g(123.23, 'q')" } ] } @@ -1333,7 +1345,9 @@ org.apache.spark.SparkNumberFormatException "queryContext" : [ { "objectType" : "", "objectName" : "", - "fragment" : "" + "startIndex" : 8, + "stopIndex" : 26, + "fragment" : "foo9h('hello', '7')" } ] } @@ -1356,7 +1370,9 @@ org.apache.spark.SparkNumberFormatException "queryContext" : [ { "objectType" : "", "objectName" : "", - "fragment" : "" + "startIndex" : 8, + "stopIndex" : 25, + "fragment" : "foo9h(123.23, 'q')" } ] }