@@ -35,6 +35,7 @@ use crate::expression::{AliasType, ScalarExpression};
3535use crate :: planner:: operator:: scalar_subquery:: ScalarSubqueryOperator ;
3636use crate :: planner:: { LogicalPlan , SchemaOutput } ;
3737use crate :: storage:: Transaction ;
38+ use crate :: types:: tuple:: SchemaRef ;
3839use crate :: types:: value:: { DataValue , Utf8Type } ;
3940use crate :: types:: { ColumnId , LogicalType } ;
4041
@@ -81,6 +82,51 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T
8182 }
8283 }
8384
85+ fn find_column_in_schema < ' b > (
86+ schema_ref : & ' b SchemaRef ,
87+ column_name : & str ,
88+ ) -> Option < ( usize , & ' b ColumnRef ) > {
89+ schema_ref
90+ . iter ( )
91+ . enumerate ( )
92+ . find ( |( _, column) | column. name ( ) == column_name)
93+ }
94+
95+ fn find_column_in_scope (
96+ context : & BinderContext < ' a , T > ,
97+ table_schema_buf : & mut HashMap < TableName , Option < SchemaOutput > > ,
98+ column_name : & str ,
99+ ) -> Option < ScalarExpression > {
100+ let mut position_offset = 0 ;
101+
102+ for bound_source in & context. bind_table {
103+ let schema_buf = table_schema_buf
104+ . entry ( bound_source. table_name . clone ( ) )
105+ . or_default ( ) ;
106+ let schema_ref = bound_source. source . schema_ref ( schema_buf) ;
107+
108+ if let Some ( ( position, column) ) = Self :: find_column_in_schema ( & schema_ref, column_name)
109+ {
110+ return Some ( ScalarExpression :: column_expr (
111+ column. clone ( ) ,
112+ position_offset + position,
113+ ) ) ;
114+ }
115+
116+ position_offset += schema_ref. len ( ) ;
117+ }
118+
119+ None
120+ }
121+
122+ fn column_not_found_with_span ( idents : & [ Ident ] , column_name : & str ) -> DatabaseError {
123+ let err = DatabaseError :: column_not_found ( column_name. to_string ( ) ) ;
124+ match idents. last ( ) {
125+ Some ( ident) => attach_span_from_sqlparser_span_if_absent ( err, ident. span ) ,
126+ None => err,
127+ }
128+ }
129+
84130 pub ( crate ) fn bind_expr ( & mut self , expr : & Expr ) -> Result < ScalarExpression , DatabaseError > {
85131 match expr {
86132 Expr :: Identifier ( ident) => {
@@ -497,69 +543,36 @@ impl<'a, T: Transaction, A: AsRef<[(&'static str, DataValue)]>> Binder<'a, '_, T
497543 }
498544 }
499545 } ;
500- let ( position, column) = schema_ref
501- . iter ( )
502- . enumerate ( )
503- . find ( |( _, column) | column. name ( ) == full_name. 1 )
504- . ok_or_else ( || {
505- let err = DatabaseError :: column_not_found ( full_name. 1 . to_string ( ) ) ;
506- match idents. last ( ) {
507- Some ( ident) => attach_span_from_sqlparser_span_if_absent ( err, ident. span ) ,
508- None => err,
509- }
510- } ) ?;
546+ let ( position, column) = Self :: find_column_in_schema ( & schema_ref, full_name. 1 . as_str ( ) )
547+ . ok_or_else ( || Self :: column_not_found_with_span ( idents, full_name. 1 . as_str ( ) ) ) ?;
511548
512549 Ok ( ScalarExpression :: column_expr (
513550 column. clone ( ) ,
514551 position_offset + position,
515552 ) )
516553 } else {
517- let op =
518- |got_column : & mut Option < ScalarExpression > ,
519- context : & BinderContext < ' a , T > ,
520- table_schema_buf : & mut HashMap < TableName , Option < SchemaOutput > > | {
521- let mut position_offset = 0 ;
522-
523- for bound_source in & context. bind_table {
524- if got_column. is_some ( ) {
525- break ;
526- }
527- let schema_buf = table_schema_buf
528- . entry ( bound_source. table_name . clone ( ) )
529- . or_default ( ) ;
530- let schema_ref = bound_source. source . schema_ref ( schema_buf) ;
531- if let Some ( ( position, column) ) = schema_ref
532- . iter ( )
533- . enumerate ( )
534- . find ( |( _, column) | column. name ( ) == full_name. 1 )
535- {
536- * got_column = Some ( ScalarExpression :: column_expr (
537- column. clone ( ) ,
538- position_offset + position,
539- ) ) ;
540- }
541- position_offset += schema_ref. len ( ) ;
542- }
543- } ;
544554 // handle col syntax
545- let mut got_column = None ;
546-
547- op ( & mut got_column, & self . context , & mut self . table_schema_buf ) ;
555+ let mut got_column = Self :: find_column_in_scope (
556+ & self . context ,
557+ & mut self . table_schema_buf ,
558+ full_name. 1 . as_str ( ) ,
559+ ) ;
548560 if got_column. is_none ( ) {
549561 if let Some ( parent) = self . parent {
550562 self . context . mark_outer_ref ( ) ;
551- op ( & mut got_column, & parent. context , & mut self . table_schema_buf ) ;
563+ got_column = Self :: find_column_in_scope (
564+ & parent. context ,
565+ & mut self . table_schema_buf ,
566+ full_name. 1 . as_str ( ) ,
567+ ) ;
552568 }
553569 }
554570 match got_column {
555571 Some ( column) => Ok ( column) ,
556- None => {
557- let err = DatabaseError :: column_not_found ( full_name. 1 . clone ( ) ) ;
558- Err ( match idents. last ( ) {
559- Some ( ident) => attach_span_from_sqlparser_span_if_absent ( err, ident. span ) ,
560- None => err,
561- } )
562- }
572+ None => Err ( Self :: column_not_found_with_span (
573+ idents,
574+ full_name. 1 . as_str ( ) ,
575+ ) ) ,
563576 }
564577 }
565578 }
0 commit comments