1414
1515use std:: collections:: btree_map;
1616use std:: collections:: BTreeMap ;
17+ use std:: collections:: BTreeSet ;
1718use std:: collections:: HashMap ;
1819use std:: collections:: HashSet ;
1920use std:: hash:: Hash ;
@@ -147,8 +148,8 @@ pub struct BindContext {
147148
148149 pub columns : Vec < ColumnBinding > ,
149150
150- // map internal column id to (table_index, column_index)
151- pub bound_internal_columns : BTreeMap < ColumnId , ( IndexType , IndexType ) > ,
151+ // map internal column: (table_index, column_id) -> column_index
152+ pub bound_internal_columns : BTreeMap < ( IndexType , ColumnId ) , IndexType > ,
152153
153154 pub aggregate_info : AggregateInfo ,
154155
@@ -578,35 +579,49 @@ impl BindContext {
578579 }
579580
580581 fn get_internal_column_table_index (
582+ & self ,
581583 column_binding : & InternalColumnBinding ,
582- metadata : MetadataRef ,
583584 ) -> Result < IndexType > {
584- let metadata = metadata. read ( ) ;
585-
586585 if let Some ( table_name) = & column_binding. table_name {
587- metadata
588- . get_table_index ( column_binding. database_name . as_deref ( ) , table_name)
589- . ok_or_else ( || {
590- ErrorCode :: TableInfoError ( format ! (
591- "Table `{table_name}` is not found in the metadata"
592- ) )
593- } )
586+ for column in & self . columns {
587+ if column_binding. database_name . is_some ( )
588+ && column. database_name != column_binding. database_name
589+ {
590+ continue ;
591+ }
592+ if column. table_name != column_binding. table_name {
593+ continue ;
594+ }
595+ if let Some ( table_index) = column. table_index {
596+ return Ok ( table_index) ;
597+ }
598+ }
599+ Err ( ErrorCode :: SemanticError ( format ! (
600+ "Table `{table_name}` is not found in the bind context"
601+ ) ) )
594602 } else {
595- let tables = metadata
596- . tables ( )
597- . iter ( )
598- . filter ( |t| !t. is_source_of_index ( ) )
599- . collect :: < Vec < _ > > ( ) ;
600- debug_assert ! ( !tables. is_empty( ) ) ;
601-
602- if tables. len ( ) > 1 {
603+ let mut table_indices = BTreeSet :: new ( ) ;
604+ for column in & self . columns {
605+ if column. table_name . is_none ( ) {
606+ continue ;
607+ }
608+ if let Some ( table_index) = column. table_index {
609+ table_indices. insert ( table_index) ;
610+ }
611+ }
612+ if table_indices. is_empty ( ) {
613+ return Err ( ErrorCode :: SemanticError ( format ! (
614+ "The table of the internal column `{}` is not found" ,
615+ column_binding. internal_column. column_name( )
616+ ) ) ) ;
617+ }
618+ if table_indices. len ( ) > 1 {
603619 return Err ( ErrorCode :: SemanticError ( format ! (
604620 "The table of the internal column `{}` is ambiguous" ,
605621 column_binding. internal_column. column_name( )
606622 ) ) ) ;
607623 }
608-
609- Ok ( tables[ 0 ] . index ( ) )
624+ Ok ( * table_indices. first ( ) . unwrap ( ) )
610625 }
611626 }
612627
@@ -615,25 +630,31 @@ impl BindContext {
615630 & mut self ,
616631 column_binding : & InternalColumnBinding ,
617632 metadata : MetadataRef ,
633+ table_index : Option < IndexType > ,
618634 visible : bool ,
619635 ) -> Result < ColumnBinding > {
620636 let column_id = column_binding. internal_column . column_id ( ) ;
621- let ( table_index, column_index, new) = match self . bound_internal_columns . entry ( column_id) {
622- btree_map:: Entry :: Vacant ( e) => {
623- let table_index =
624- BindContext :: get_internal_column_table_index ( column_binding, metadata. clone ( ) ) ?;
625- let mut metadata = metadata. write ( ) ;
626- let column_index = metadata
627- . add_internal_column ( table_index, column_binding. internal_column . clone ( ) ) ;
628- e. insert ( ( table_index, column_index) ) ;
629- ( table_index, column_index, true )
630- }
631- btree_map:: Entry :: Occupied ( e) => {
632- let ( table_index, column_index) = e. get ( ) ;
633- ( * table_index, * column_index, false )
634- }
637+ let table_index = if let Some ( table_index) = table_index {
638+ table_index
639+ } else {
640+ self . get_internal_column_table_index ( column_binding) ?
635641 } ;
636642
643+ let ( column_index, is_new) =
644+ match self . bound_internal_columns . entry ( ( table_index, column_id) ) {
645+ btree_map:: Entry :: Vacant ( e) => {
646+ let mut metadata = metadata. write ( ) ;
647+ let column_index = metadata
648+ . add_internal_column ( table_index, column_binding. internal_column . clone ( ) ) ;
649+ e. insert ( column_index) ;
650+ ( column_index, true )
651+ }
652+ btree_map:: Entry :: Occupied ( e) => {
653+ let column_index = e. get ( ) ;
654+ ( * column_index, false )
655+ }
656+ } ;
657+
637658 let metadata = metadata. read ( ) ;
638659 let table = metadata. table ( table_index) ;
639660 if !table. table ( ) . supported_internal_column ( column_id) {
@@ -660,7 +681,7 @@ impl BindContext {
660681 . table_index ( Some ( table_index) )
661682 . build ( ) ;
662683
663- if new {
684+ if is_new {
664685 debug_assert ! ( !self . columns. iter( ) . any( |c| c == & column_binding) ) ;
665686 self . columns . push ( column_binding. clone ( ) ) ;
666687 }
0 commit comments