@@ -180,8 +180,8 @@ abstract class LogicalPlan extends QueryPlan[LogicalPlan] with Logging {
180180
181181/**
182182 * Helper class for (LogicalPlan) attribute resolution. This class indexes attributes by their
183- * case-in-sensitive name, and checks potential candidates using the given Resolver. Both qualified
184- * and direct resolution are supported.
183+ * case-in-sensitive name, and checks potential candidates using the [[ Resolver ]] passed to the
184+ * resolve(...) function. Both qualified and direct resolution are supported.
185185 */
186186private [catalyst] class AttributeResolver (attributes : Seq [Attribute ]) extends Logging {
187187 private def unique [T ](m : Map [T , Seq [Attribute ]]): Map [T , Seq [Attribute ]] = {
@@ -203,8 +203,12 @@ private[catalyst] class AttributeResolver(attributes: Seq[Attribute]) extends Lo
203203
204204 /** Perform attribute resolution given a name and a resolver. */
205205 def resolve (nameParts : Seq [String ], resolver : Resolver ): Option [NamedExpression ] = {
206- // Check if the attribute is a match for the given name.
207- def isMatch (name : String , a : Attribute ): Boolean = ! a.isGenerated && resolver(a.name, name)
206+ // Collect matching attributes given a name and a lookup.
207+ def collectMatches (name : String , candidates : Option [Seq [Attribute ]]): Seq [Attribute ] = {
208+ candidates.toSeq.flatMap(_.collect {
209+ case a if ! a.isGenerated && resolver(a.name, name) => a.withName(name)
210+ })
211+ }
208212
209213 // Find matches for the given name assuming that the 1st part is a qualifier (i.e. table name,
210214 // alias, or subquery alias) and the 2nd part is the actual name. This returns a tuple of
@@ -216,9 +220,9 @@ private[catalyst] class AttributeResolver(attributes: Seq[Attribute]) extends Lo
216220 val matches = nameParts match {
217221 case qualifier +: name +: nestedFields =>
218222 val key = (qualifier.toLowerCase, name.toLowerCase)
219- val attributes = qualified.get(key).toSeq.flatMap(_ .filter { a =>
220- resolver(qualifier, a.qualifier.get) && isMatch(name, a)
221- })
223+ val attributes = collectMatches(name, qualified.get(key)) .filter { a =>
224+ resolver(qualifier, a.qualifier.get)
225+ }
222226 (attributes, nestedFields)
223227 case all =>
224228 (Nil , all)
@@ -228,7 +232,7 @@ private[catalyst] class AttributeResolver(attributes: Seq[Attribute]) extends Lo
228232 val (candidates, nestedFields) = matches match {
229233 case (Seq (), _) =>
230234 val name = nameParts.head
231- val attributes = direct.get(name.toLowerCase).toSeq.flatMap(_.filter(isMatch(name, _) ))
235+ val attributes = collectMatches(name, direct.get(name.toLowerCase))
232236 (attributes, nameParts.tail)
233237 case _ => matches
234238 }
0 commit comments