@@ -133,6 +133,23 @@ pub fn hover(file: &ast::SourceFile, offset: TextSize) -> Option<String> {
133133 if let Some ( create_schema) = name. syntax ( ) . ancestors ( ) . find_map ( ast:: CreateSchema :: cast) {
134134 return format_create_schema ( & create_schema) ;
135135 }
136+
137+ // create view t(x) as select 1;
138+ // ^
139+ if let Some ( column_list) = name. syntax ( ) . ancestors ( ) . find_map ( ast:: ColumnList :: cast)
140+ && let Some ( create_view) = column_list
141+ . syntax ( )
142+ . ancestors ( )
143+ . find_map ( ast:: CreateView :: cast)
144+ {
145+ return format_view_column ( & create_view, Name :: from_node ( & name) , & binder) ;
146+ }
147+
148+ // create view t as select 1;
149+ // ^
150+ if let Some ( create_view) = name. syntax ( ) . ancestors ( ) . find_map ( ast:: CreateView :: cast) {
151+ return format_create_view ( & create_view, & binder) ;
152+ }
136153 }
137154
138155 None
@@ -170,6 +187,16 @@ fn hover_column(
170187 return Some ( format ! ( "column {}.{}" , cte_name, column_name) ) ;
171188 }
172189
190+ // create view v(a) as select 1;
191+ // select a from v;
192+ // ^
193+ if let Some ( create_view) = column_name_node. ancestors ( ) . find_map ( ast:: CreateView :: cast)
194+ && let Some ( column_name) =
195+ ast:: Name :: cast ( column_name_node. clone ( ) ) . map ( |name| Name :: from_node ( & name) )
196+ {
197+ return format_view_column ( & create_view, column_name, binder) ;
198+ }
199+
173200 let column = column_name_node. ancestors ( ) . find_map ( ast:: Column :: cast) ?;
174201 let column_name = column. name ( ) ?. syntax ( ) . text ( ) . to_string ( ) ;
175202 let ty = column. ty ( ) ?;
@@ -233,6 +260,13 @@ fn hover_table(
233260 return format_with_table ( & with_table) ;
234261 }
235262
263+ // create view v as select 1 a;
264+ // select a from v;
265+ // ^
266+ if let Some ( create_view) = table_name_node. ancestors ( ) . find_map ( ast:: CreateView :: cast) {
267+ return format_create_view ( & create_view, binder) ;
268+ }
269+
236270 let create_table = table_name_node
237271 . ancestors ( )
238272 . find_map ( ast:: CreateTable :: cast) ?;
@@ -289,6 +323,48 @@ fn format_create_table(create_table: &ast::CreateTable, binder: &binder::Binder)
289323 Some ( format ! ( "table {}.{}{}" , schema, table_name, args) )
290324}
291325
326+ fn format_create_view ( create_view : & ast:: CreateView , binder : & binder:: Binder ) -> Option < String > {
327+ let path = create_view. path ( ) ?;
328+ let segment = path. segment ( ) ?;
329+ let view_name = segment. name ( ) ?. syntax ( ) . text ( ) . to_string ( ) ;
330+
331+ let schema = if let Some ( qualifier) = path. qualifier ( ) {
332+ qualifier. syntax ( ) . text ( ) . to_string ( )
333+ } else {
334+ view_schema ( create_view, binder) ?
335+ } ;
336+
337+ let column_list = create_view
338+ . column_list ( )
339+ . map ( |cl| cl. syntax ( ) . text ( ) . to_string ( ) )
340+ . unwrap_or_default ( ) ;
341+
342+ let query = create_view. query ( ) ?. syntax ( ) . text ( ) . to_string ( ) ;
343+
344+ Some ( format ! (
345+ "view {}.{}{} as {}" ,
346+ schema, view_name, column_list, query
347+ ) )
348+ }
349+
350+ fn format_view_column (
351+ create_view : & ast:: CreateView ,
352+ column_name : Name ,
353+ binder : & binder:: Binder ,
354+ ) -> Option < String > {
355+ let path = create_view. path ( ) ?;
356+ let segment = path. segment ( ) ?;
357+ let view_name = Name :: from_node ( & segment. name ( ) ?) ;
358+
359+ let schema = if let Some ( qualifier) = path. qualifier ( ) {
360+ Name :: from_string ( qualifier. syntax ( ) . text ( ) . to_string ( ) )
361+ } else {
362+ Name :: from_string ( view_schema ( create_view, binder) ?)
363+ } ;
364+
365+ Some ( format ! ( "column {}.{}.{}" , schema, view_name, column_name) )
366+ }
367+
292368fn format_with_table ( with_table : & ast:: WithTable ) -> Option < String > {
293369 let name = with_table. name ( ) ?. syntax ( ) . text ( ) . to_string ( ) ;
294370 let query = with_table. query ( ) ?. syntax ( ) . text ( ) . to_string ( ) ;
@@ -306,6 +382,17 @@ fn table_schema(create_table: &ast::CreateTable, binder: &binder::Binder) -> Opt
306382 search_path. first ( ) . map ( |s| s. to_string ( ) )
307383}
308384
385+ fn view_schema ( create_view : & ast:: CreateView , binder : & binder:: Binder ) -> Option < String > {
386+ let is_temp = create_view. temp_token ( ) . is_some ( ) || create_view. temporary_token ( ) . is_some ( ) ;
387+ if is_temp {
388+ return Some ( "pg_temp" . to_string ( ) ) ;
389+ }
390+
391+ let position = create_view. syntax ( ) . text_range ( ) . start ( ) ;
392+ let search_path = binder. search_path_at ( position) ;
393+ search_path. first ( ) . map ( |s| s. to_string ( ) )
394+ }
395+
309396fn format_create_index ( create_index : & ast:: CreateIndex , binder : & binder:: Binder ) -> Option < String > {
310397 let index_name = create_index. name ( ) ?. syntax ( ) . text ( ) . to_string ( ) ;
311398
@@ -414,6 +501,9 @@ fn is_table_ref(name_ref: &ast::NameRef) -> bool {
414501 if ast:: DropTable :: can_cast ( ancestor. kind ( ) ) {
415502 return true ;
416503 }
504+ if ast:: DropView :: can_cast ( ancestor. kind ( ) ) {
505+ return true ;
506+ }
417507 if ast:: Table :: can_cast ( ancestor. kind ( ) ) {
418508 return true ;
419509 }
@@ -2644,4 +2734,130 @@ update users set email = new_data.email from new_data where new_data.id$0 = user
26442734 ╰╴ ─ hover
26452735 " ) ;
26462736 }
2737+
2738+ #[ test]
2739+ fn hover_on_create_view_definition ( ) {
2740+ assert_snapshot ! ( check_hover( "
2741+ create view v$0 as select 1;
2742+ " ) , @r"
2743+ hover: view public.v as select 1
2744+ ╭▸
2745+ 2 │ create view v as select 1;
2746+ ╰╴ ─ hover
2747+ " ) ;
2748+ }
2749+
2750+ #[ test]
2751+ fn hover_on_create_view_definition_with_schema ( ) {
2752+ assert_snapshot ! ( check_hover( "
2753+ create view myschema.v$0 as select 1;
2754+ " ) , @r"
2755+ hover: view myschema.v as select 1
2756+ ╭▸
2757+ 2 │ create view myschema.v as select 1;
2758+ ╰╴ ─ hover
2759+ " ) ;
2760+ }
2761+
2762+ #[ test]
2763+ fn hover_on_create_temp_view_definition ( ) {
2764+ assert_snapshot ! ( check_hover( "
2765+ create temp view v$0 as select 1;
2766+ " ) , @r"
2767+ hover: view pg_temp.v as select 1
2768+ ╭▸
2769+ 2 │ create temp view v as select 1;
2770+ ╰╴ ─ hover
2771+ " ) ;
2772+ }
2773+
2774+ #[ test]
2775+ fn hover_on_create_view_with_column_list ( ) {
2776+ assert_snapshot ! ( check_hover( "
2777+ create view v(col1$0) as select 1;
2778+ " ) , @r"
2779+ hover: column public.v.col1
2780+ ╭▸
2781+ 2 │ create view v(col1) as select 1;
2782+ ╰╴ ─ hover
2783+ " ) ;
2784+ }
2785+
2786+ #[ test]
2787+ fn hover_on_select_from_view ( ) {
2788+ assert_snapshot ! ( check_hover( "
2789+ create view v as select 1;
2790+ select * from v$0;
2791+ " ) , @r"
2792+ hover: view public.v as select 1
2793+ ╭▸
2794+ 3 │ select * from v;
2795+ ╰╴ ─ hover
2796+ " ) ;
2797+ }
2798+
2799+ #[ test]
2800+ fn hover_on_select_column_from_view_column_list ( ) {
2801+ assert_snapshot ! ( check_hover( "
2802+ create view v(a) as select 1;
2803+ select a$0 from v;
2804+ " ) , @r"
2805+ hover: column public.v.a
2806+ ╭▸
2807+ 3 │ select a from v;
2808+ ╰╴ ─ hover
2809+ " ) ;
2810+ }
2811+
2812+ #[ test]
2813+ fn hover_on_select_column_from_view_column_list_overrides_target ( ) {
2814+ assert_snapshot ! ( check_hover( "
2815+ create view v(a) as select 1, 2 b;
2816+ select a, b$0 from v;
2817+ " ) , @r"
2818+ hover: column public.v.b
2819+ ╭▸
2820+ 3 │ select a, b from v;
2821+ ╰╴ ─ hover
2822+ " ) ;
2823+ }
2824+
2825+ #[ test]
2826+ fn hover_on_select_column_from_view_target_list ( ) {
2827+ assert_snapshot ! ( check_hover( "
2828+ create view v as select 1 a, 2 b;
2829+ select a$0, b from v;
2830+ " ) , @r"
2831+ hover: column public.v.a
2832+ ╭▸
2833+ 3 │ select a, b from v;
2834+ ╰╴ ─ hover
2835+ " ) ;
2836+ }
2837+
2838+ #[ test]
2839+ fn hover_on_select_from_view_with_schema ( ) {
2840+ assert_snapshot ! ( check_hover( "
2841+ create view myschema.v as select 1;
2842+ select * from myschema.v$0;
2843+ " ) , @r"
2844+ hover: view myschema.v as select 1
2845+ ╭▸
2846+ 3 │ select * from myschema.v;
2847+ ╰╴ ─ hover
2848+ " ) ;
2849+ }
2850+
2851+ #[ test]
2852+ fn hover_on_drop_view ( ) {
2853+ assert_snapshot ! ( check_hover( "
2854+ create view v as select 1;
2855+ drop view v$0;
2856+ " ) , @r"
2857+ hover: view public.v as select 1
2858+ ╭▸
2859+ 3 │ drop view v;
2860+ ╰╴ ─ hover
2861+ " ) ;
2862+ }
26472863}
0 commit comments