diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/ColumnResolutionHelper.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/ColumnResolutionHelper.scala index e869cb281ce05..6563007a3082f 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/ColumnResolutionHelper.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/ColumnResolutionHelper.scala @@ -196,6 +196,8 @@ trait ColumnResolutionHelper extends Logging with DataTypeErrorsBase { u.copy(child = newChild) } + case s : ScopedExpression => s.mapScope(innerResolve(_, isTopLevel = false)) + case _ => e.mapChildren(innerResolve(_, isTopLevel = false)) } resolved.copyTagsFrom(e) diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/scopes.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/scopes.scala index 6739586d66101..8a2322aaf3762 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/scopes.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/scopes.scala @@ -35,6 +35,15 @@ case class ScopedExpression(expr: Expression, scope: Seq[Attribute]) override def sql: String = s"$prettyName(${expr.sql}, $scope)" override lazy val resolved: Boolean = expr.resolved + def mapScope(f: Expression => Expression): Expression = { + // similar to mapChildren, but only for the scope children + if (scope.nonEmpty) { + this.copy(scope = scope.map(f).map(_.asInstanceOf[Attribute])) + } else { + this + } + } + override protected def withNewChildrenInternal(children: IndexedSeq[Expression]): Expression = { val scope = children.tail assert(scope.forall(_.isInstanceOf[Attribute]), "Scope children have to be attributes")