@@ -419,10 +419,7 @@ impl DFSchema {
419419 name : & str ,
420420 ) -> Result < ( Option < & TableReference > , & Field ) > {
421421 if let Some ( qualifier) = qualifier {
422- let idx = self
423- . index_of_column_by_name ( Some ( qualifier) , name)
424- . ok_or_else ( || field_not_found ( Some ( qualifier. clone ( ) ) , name, self ) ) ?;
425- Ok ( ( self . field_qualifiers [ idx] . as_ref ( ) , self . field ( idx) ) )
422+ self . qualified_field_with_qualified_name ( qualifier, name)
426423 } else {
427424 self . qualified_field_with_unqualified_name ( name)
428425 }
@@ -467,6 +464,36 @@ impl DFSchema {
467464 . collect ( )
468465 }
469466
467+ /// Find all fields that match the given name with qualifier and return them with their qualifier
468+ pub fn qualified_fields_with_qualified_name (
469+ & self ,
470+ qualifier : & TableReference ,
471+ name : & str ,
472+ ) -> Vec < ( Option < & TableReference > , & Field ) > {
473+ self . iter ( )
474+ . filter ( |( q, f) | match ( qualifier, q) {
475+ // field to lookup is qualified.
476+ // current field is qualified and not shared between relations, compare both
477+ // qualifier and name.
478+ ( q, Some ( field_q) ) => q. resolved_eq ( field_q) && f. name ( ) == name,
479+ // field to lookup is qualified but current field is unqualified.
480+ ( qq, None ) => {
481+ // the original field may now be aliased with a name that matches the
482+ // original qualified name
483+ let column = Column :: from_qualified_name ( f. name ( ) ) ;
484+ match column {
485+ Column {
486+ relation : Some ( r) ,
487+ name : column_name,
488+ } => & r == qq && column_name == name,
489+ _ => false ,
490+ }
491+ }
492+ } )
493+ . map ( |( qualifier, field) | ( qualifier, field. as_ref ( ) ) )
494+ . collect ( )
495+ }
496+
470497 /// Find all fields that match the given name and convert to column
471498 pub fn columns_with_unqualified_name ( & self , name : & str ) -> Vec < Column > {
472499 self . iter ( )
@@ -519,6 +546,25 @@ impl DFSchema {
519546 }
520547 }
521548
549+ /// Find the qualified field with the given qualified name
550+ pub fn qualified_field_with_qualified_name (
551+ & self ,
552+ qualifier : & TableReference ,
553+ name : & str ,
554+ ) -> Result < ( Option < & TableReference > , & Field ) > {
555+ let matches = self . qualified_fields_with_qualified_name ( qualifier, name) ;
556+ match matches. len ( ) {
557+ 0 => Err ( field_not_found ( Some ( qualifier. clone ( ) ) , name, self ) ) ,
558+ 1 => Ok ( ( matches[ 0 ] . 0 , ( matches[ 0 ] . 1 ) ) ) ,
559+ _ => _schema_err ! ( SchemaError :: AmbiguousReference {
560+ field: Column {
561+ relation: None ,
562+ name: name. to_string( ) ,
563+ } ,
564+ } ) ,
565+ }
566+ }
567+
522568 /// Find the field with the given name
523569 pub fn field_with_unqualified_name ( & self , name : & str ) -> Result < & Field > {
524570 self . qualified_field_with_unqualified_name ( name)
0 commit comments