@@ -47,13 +47,66 @@ pub fn document_symbols(file: &ast::SourceFile) -> Vec<DocumentSymbol> {
4747 symbols. push ( symbol) ;
4848 }
4949 }
50+ ast:: Stmt :: Select ( select) => {
51+ symbols. extend ( cte_table_symbols ( select) ) ;
52+ }
53+ ast:: Stmt :: SelectInto ( select_into) => {
54+ symbols. extend ( cte_table_symbols ( select_into) ) ;
55+ }
56+ ast:: Stmt :: Insert ( insert) => {
57+ symbols. extend ( cte_table_symbols ( insert) ) ;
58+ }
59+ ast:: Stmt :: Update ( update) => {
60+ symbols. extend ( cte_table_symbols ( update) ) ;
61+ }
62+ ast:: Stmt :: Delete ( delete) => {
63+ symbols. extend ( cte_table_symbols ( delete) ) ;
64+ }
65+
5066 _ => { }
5167 }
5268 }
5369
5470 symbols
5571}
5672
73+ fn cte_table_symbols ( stmt : impl ast:: HasWithClause ) -> Vec < DocumentSymbol > {
74+ let Some ( with_clause) = stmt. with_clause ( ) else {
75+ return vec ! [ ] ;
76+ } ;
77+
78+ with_clause
79+ . with_tables ( )
80+ . filter_map ( create_cte_table_symbol)
81+ . collect ( )
82+ }
83+
84+ fn create_cte_table_symbol ( with_table : ast:: WithTable ) -> Option < DocumentSymbol > {
85+ let name_node = with_table. name ( ) ?;
86+ let name = name_node. syntax ( ) . text ( ) . to_string ( ) ;
87+
88+ let full_range = with_table. syntax ( ) . text_range ( ) ;
89+ let focus_range = name_node. syntax ( ) . text_range ( ) ;
90+
91+ let mut children = vec ! [ ] ;
92+ if let Some ( column_list) = with_table. column_list ( ) {
93+ for column in column_list. columns ( ) {
94+ if let Some ( column_symbol) = create_column_symbol ( column) {
95+ children. push ( column_symbol) ;
96+ }
97+ }
98+ }
99+
100+ Some ( DocumentSymbol {
101+ name,
102+ detail : None ,
103+ kind : DocumentSymbolKind :: Table ,
104+ full_range,
105+ focus_range,
106+ children,
107+ } )
108+ }
109+
57110fn create_table_symbol (
58111 binder : & binder:: Binder ,
59112 create_table : ast:: CreateTable ,
@@ -559,4 +612,64 @@ create function my_schema.hello() returns void as $$ select 1; $$ language sql;
559612 fn non_create_statements ( ) {
560613 symbols_not_found ( "select * from users;" )
561614 }
615+
616+ #[ test]
617+ fn cte_table ( ) {
618+ assert_snapshot ! (
619+ symbols( "
620+ with recent_users as (
621+ select id, email as user_email
622+ from users
623+ )
624+ select * from recent_users;
625+ " ) ,
626+ @r"
627+ info: table: recent_users
628+ ╭▸
629+ 2 │ with recent_users as (
630+ │ │━━━━━━━━━━━
631+ │ │
632+ │ ┌──────focus range
633+ │ │
634+ 3 │ │ select id, email as user_email
635+ 4 │ │ from users
636+ 5 │ │ )
637+ ╰╴└─┘ full range
638+ "
639+ ) ;
640+ }
641+
642+ #[ test]
643+ fn cte_table_with_column_list ( ) {
644+ assert_snapshot ! (
645+ symbols( "
646+ with t(a, b, c) as (
647+ select 1, 2, 3
648+ )
649+ select * from t;
650+ " ) ,
651+ @r"
652+ info: table: t
653+ ╭▸
654+ 2 │ with t(a, b, c) as (
655+ │ ━ focus range
656+ │ ┌──────┘
657+ │ │
658+ 3 │ │ select 1, 2, 3
659+ 4 │ │ )
660+ │ └─┘ full range
661+ │
662+ ⸬
663+ 2 │ with t(a, b, c) as (
664+ │ ┯ ┯ ┯
665+ │ │ │ │
666+ │ │ │ full range for `column: c`
667+ │ │ │ focus range
668+ │ │ full range for `column: b`
669+ │ │ focus range
670+ │ full range for `column: a`
671+ ╰╴ focus range
672+ "
673+ ) ;
674+ }
562675}
0 commit comments