@@ -5,6 +5,7 @@ use squawk_syntax::{
55} ;
66
77use crate :: binder:: Binder ;
8+ use crate :: column_name:: ColumnName ;
89pub ( crate ) use crate :: symbols:: Schema ;
910use crate :: symbols:: { Name , SymbolKind } ;
1011
@@ -56,6 +57,13 @@ pub(crate) fn resolve_name_ref(binder: &Binder, name_ref: &ast::NameRef) -> Opti
5657 } else {
5758 None
5859 } ;
60+
61+ if schema. is_none ( )
62+ && let Some ( cte_ptr) = resolve_cte_table ( name_ref, & table_name)
63+ {
64+ return Some ( cte_ptr) ;
65+ }
66+
5967 let position = name_ref. syntax ( ) . text_range ( ) . start ( ) ;
6068 resolve_table ( binder, & table_name, & schema, position)
6169 }
@@ -593,6 +601,12 @@ fn resolve_select_column(binder: &Binder, name_ref: &ast::NameRef) -> Option<Syn
593601 ( table_name, Some ( schema) )
594602 } ;
595603
604+ if schema. is_none ( )
605+ && let Some ( cte_column_ptr) = resolve_cte_column ( & select, & table_name, & column_name)
606+ {
607+ return Some ( cte_column_ptr) ;
608+ }
609+
596610 let position = name_ref. syntax ( ) . text_range ( ) . start ( ) ;
597611 let table_ptr = resolve_table ( binder, & table_name, & schema, position) ?;
598612
@@ -757,6 +771,60 @@ pub(crate) fn find_column_in_table(
757771 } )
758772}
759773
774+ fn resolve_cte_table ( name_ref : & ast:: NameRef , cte_name : & Name ) -> Option < SyntaxNodePtr > {
775+ let select = name_ref. syntax ( ) . ancestors ( ) . find_map ( ast:: Select :: cast) ?;
776+ let with_clause = select. with_clause ( ) ?;
777+
778+ for with_table in with_clause. with_tables ( ) {
779+ if let Some ( name) = with_table. name ( )
780+ && Name :: new ( name. syntax ( ) . text ( ) . to_string ( ) ) == * cte_name
781+ {
782+ return Some ( SyntaxNodePtr :: new ( name. syntax ( ) ) ) ;
783+ }
784+ }
785+
786+ None
787+ }
788+
789+ fn resolve_cte_column (
790+ select : & ast:: Select ,
791+ cte_name : & Name ,
792+ column_name : & Name ,
793+ ) -> Option < SyntaxNodePtr > {
794+ let with_clause = select. with_clause ( ) ?;
795+
796+ for with_table in with_clause. with_tables ( ) {
797+ if let Some ( name) = with_table. name ( )
798+ && Name :: new ( name. syntax ( ) . text ( ) . to_string ( ) ) == * cte_name
799+ {
800+ let query = with_table. query ( ) ?;
801+
802+ let cte_select = match query {
803+ ast:: WithQuery :: Select ( s) => s,
804+ ast:: WithQuery :: ParenSelect ( ps) => match ps. select ( ) ? {
805+ ast:: SelectVariant :: Select ( s) => s,
806+ _ => continue ,
807+ } ,
808+ _ => continue ,
809+ } ;
810+
811+ let select_clause = cte_select. select_clause ( ) ?;
812+ let target_list = select_clause. target_list ( ) ?;
813+
814+ 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) ) ;
820+ }
821+ }
822+ }
823+ }
824+
825+ None
826+ }
827+
760828pub ( crate ) fn resolve_insert_table_columns (
761829 file : & ast:: SourceFile ,
762830 binder : & Binder ,
0 commit comments