@@ -602,7 +602,7 @@ fn resolve_select_column(binder: &Binder, name_ref: &ast::NameRef) -> Option<Syn
602602 } ;
603603
604604 if schema. is_none ( )
605- && let Some ( cte_column_ptr) = resolve_cte_column ( & select , & table_name, & column_name)
605+ && let Some ( cte_column_ptr) = resolve_cte_column ( name_ref , & table_name, & column_name)
606606 {
607607 return Some ( cte_column_ptr) ;
608608 }
@@ -787,16 +787,41 @@ fn resolve_cte_table(name_ref: &ast::NameRef, cte_name: &Name) -> Option<SyntaxN
787787}
788788
789789fn resolve_cte_column (
790- select : & ast:: Select ,
790+ name_ref : & ast:: NameRef ,
791791 cte_name : & Name ,
792792 column_name : & Name ,
793793) -> Option < SyntaxNodePtr > {
794+ let select = name_ref
795+ . syntax ( )
796+ . ancestors ( )
797+ . filter_map ( ast:: Select :: cast)
798+ . find ( |s| s. with_clause ( ) . is_some ( ) ) ?;
794799 let with_clause = select. with_clause ( ) ?;
795800
796801 for with_table in with_clause. with_tables ( ) {
797802 if let Some ( name) = with_table. name ( )
798803 && Name :: new ( name. syntax ( ) . text ( ) . to_string ( ) ) == * cte_name
799804 {
805+ // Skip if we're inside this CTE's definition (CTE doesn't shadow itself)
806+ if with_table
807+ . syntax ( )
808+ . text_range ( )
809+ . contains_range ( name_ref. syntax ( ) . text_range ( ) )
810+ {
811+ continue ;
812+ }
813+
814+ if let Some ( column_list) = with_table. column_list ( ) {
815+ for column in column_list. columns ( ) {
816+ if let Some ( col_name) = column. name ( )
817+ && Name :: new ( col_name. syntax ( ) . text ( ) . to_string ( ) ) == * column_name
818+ {
819+ return Some ( SyntaxNodePtr :: new ( col_name. syntax ( ) ) ) ;
820+ }
821+ }
822+ return None ;
823+ }
824+
800825 let query = with_table. query ( ) ?;
801826
802827 let cte_select = match query {
@@ -812,11 +837,23 @@ fn resolve_cte_column(
812837 let target_list = select_clause. target_list ( ) ?;
813838
814839 for target in target_list. targets ( ) {
815- if let Some ( ( col_name, node) ) = ColumnName :: from_target ( target)
816- && let Some ( col_name_str) = col_name. to_string ( )
817- && Name :: new ( col_name_str) == * column_name
818- {
819- return Some ( SyntaxNodePtr :: new ( & node) ) ;
840+ if let Some ( ( col_name, node) ) = ColumnName :: from_target ( target. clone ( ) ) {
841+ if let Some ( col_name_str) = col_name. to_string ( )
842+ && Name :: new ( col_name_str) == * column_name
843+ {
844+ return Some ( SyntaxNodePtr :: new ( & node) ) ;
845+ }
846+
847+ if matches ! ( col_name, ColumnName :: Star ) {
848+ if let Some ( from_clause) = cte_select. from_clause ( )
849+ && let Some ( from_item) = from_clause. from_items ( ) . next ( )
850+ && let Some ( from_name_ref) = from_item. name_ref ( )
851+ {
852+ let from_table_name =
853+ Name :: new ( from_name_ref. syntax ( ) . text ( ) . to_string ( ) ) ;
854+ return resolve_cte_column ( name_ref, & from_table_name, column_name) ;
855+ }
856+ }
820857 }
821858 }
822859 }
0 commit comments