1- use std:: ops:: Range ;
1+ use std:: {
2+ collections:: { HashMap , HashSet } ,
3+ hash:: Hash ,
4+ ops:: Range ,
5+ } ;
26
37use pg_schema_cache:: SchemaCache ;
4- use pg_treesitter_queries:: { queries, TreeSitterQueriesExecutor } ;
8+ use pg_treesitter_queries:: {
9+ queries:: { self , QueryResult } ,
10+ TreeSitterQueriesExecutor ,
11+ } ;
512
613use crate :: CompletionParams ;
714
@@ -57,11 +64,11 @@ pub(crate) struct CompletionContext<'a> {
5764 pub is_invocation : bool ,
5865 pub wrapping_statement_range : Option < Range < usize > > ,
5966
60- pub ts_query_executor : Option < TreeSitterQueriesExecutor < ' a > > ,
67+ pub mentioned_relations : HashMap < Option < String > , HashSet < String > > ,
6168}
6269
6370impl < ' a > CompletionContext < ' a > {
64- pub async fn new ( params : & ' a CompletionParams < ' a > ) -> Self {
71+ pub fn new ( params : & ' a CompletionParams < ' a > ) -> Self {
6572 let mut ctx = Self {
6673 tree : params. tree ,
6774 text : & params. text ,
@@ -73,26 +80,49 @@ impl<'a> CompletionContext<'a> {
7380 wrapping_clause_type : None ,
7481 wrapping_statement_range : None ,
7582 is_invocation : false ,
76- ts_query_executor : None ,
83+ mentioned_relations : HashMap :: new ( ) ,
7784 } ;
7885
7986 ctx. gather_tree_context ( ) ;
80- ctx. dispatch_ts_queries ( ) . await ;
87+ ctx. gather_info_from_ts_queries ( ) ;
8188
8289 ctx
8390 }
8491
85- async fn dispatch_ts_queries ( & mut self ) {
92+ fn gather_info_from_ts_queries ( & mut self ) {
8693 let tree = match self . tree . as_ref ( ) {
8794 None => return ,
8895 Some ( t) => t,
8996 } ;
9097
91- let mut executor = TreeSitterQueriesExecutor :: new ( tree. root_node ( ) , self . text ) ;
98+ let stmt_range = self . wrapping_statement_range . as_ref ( ) ;
99+ let sql = self . text ;
92100
93- executor. add_query_results :: < queries :: RelationMatch > ( ) . await ;
101+ let mut executor = TreeSitterQueriesExecutor :: new ( tree . root_node ( ) , self . text ) ;
94102
95- self . ts_query_executor = Some ( executor) ;
103+ executor. add_query_results :: < queries:: RelationMatch > ( ) ;
104+
105+ for relation_match in executor. get_iter ( stmt_range) {
106+ match relation_match {
107+ QueryResult :: Relation ( r) => {
108+ let schema_name = r. get_schema ( sql) ;
109+ let table_name = r. get_table ( sql) ;
110+
111+ let current = self . mentioned_relations . get_mut ( & schema_name) ;
112+
113+ match current {
114+ Some ( c) => {
115+ c. insert ( table_name) ;
116+ }
117+ None => {
118+ let mut new = HashSet :: new ( ) ;
119+ new. insert ( table_name) ;
120+ self . mentioned_relations . insert ( schema_name, new) ;
121+ }
122+ } ;
123+ }
124+ } ;
125+ }
96126 }
97127
98128 pub fn get_ts_node_content ( & self , ts_node : tree_sitter:: Node < ' a > ) -> Option < & ' a str > {
@@ -203,8 +233,8 @@ mod tests {
203233 parser. parse ( input, None ) . expect ( "Unable to parse tree" )
204234 }
205235
206- #[ tokio :: test]
207- async fn identifies_clauses ( ) {
236+ #[ test]
237+ fn identifies_clauses ( ) {
208238 let test_cases = vec ! [
209239 ( format!( "Select {}* from users;" , CURSOR_POS ) , "select" ) ,
210240 ( format!( "Select * from u{};" , CURSOR_POS ) , "from" ) ,
@@ -244,14 +274,14 @@ mod tests {
244274 schema : & pg_schema_cache:: SchemaCache :: new ( ) ,
245275 } ;
246276
247- let ctx = CompletionContext :: new ( & params) . await ;
277+ let ctx = CompletionContext :: new ( & params) ;
248278
249279 assert_eq ! ( ctx. wrapping_clause_type, expected_clause. try_into( ) . ok( ) ) ;
250280 }
251281 }
252282
253- #[ tokio :: test]
254- async fn identifies_schema ( ) {
283+ #[ test]
284+ fn identifies_schema ( ) {
255285 let test_cases = vec ! [
256286 (
257287 format!( "Select * from private.u{}" , CURSOR_POS ) ,
@@ -276,14 +306,14 @@ mod tests {
276306 schema : & pg_schema_cache:: SchemaCache :: new ( ) ,
277307 } ;
278308
279- let ctx = CompletionContext :: new ( & params) . await ;
309+ let ctx = CompletionContext :: new ( & params) ;
280310
281311 assert_eq ! ( ctx. schema_name, expected_schema. map( |f| f. to_string( ) ) ) ;
282312 }
283313 }
284314
285- #[ tokio :: test]
286- async fn identifies_invocation ( ) {
315+ #[ test]
316+ fn identifies_invocation ( ) {
287317 let test_cases = vec ! [
288318 ( format!( "Select * from u{}sers" , CURSOR_POS ) , false ) ,
289319 ( format!( "Select * from u{}sers()" , CURSOR_POS ) , true ) ,
@@ -310,14 +340,14 @@ mod tests {
310340 schema : & pg_schema_cache:: SchemaCache :: new ( ) ,
311341 } ;
312342
313- let ctx = CompletionContext :: new ( & params) . await ;
343+ let ctx = CompletionContext :: new ( & params) ;
314344
315345 assert_eq ! ( ctx. is_invocation, is_invocation) ;
316346 }
317347 }
318348
319- #[ tokio :: test]
320- async fn does_not_fail_on_leading_whitespace ( ) {
349+ #[ test]
350+ fn does_not_fail_on_leading_whitespace ( ) {
321351 let cases = vec ! [
322352 format!( "{} select * from" , CURSOR_POS ) ,
323353 format!( " {} select * from" , CURSOR_POS ) ,
@@ -335,7 +365,7 @@ mod tests {
335365 schema : & pg_schema_cache:: SchemaCache :: new ( ) ,
336366 } ;
337367
338- let ctx = CompletionContext :: new ( & params) . await ;
368+ let ctx = CompletionContext :: new ( & params) ;
339369
340370 let node = ctx. ts_node . unwrap ( ) ;
341371
@@ -348,8 +378,8 @@ mod tests {
348378 }
349379 }
350380
351- #[ tokio :: test]
352- async fn does_not_fail_on_trailing_whitespace ( ) {
381+ #[ test]
382+ fn does_not_fail_on_trailing_whitespace ( ) {
353383 let query = format ! ( "select * from {}" , CURSOR_POS ) ;
354384
355385 let ( position, text) = get_text_and_position ( query. as_str ( ) ) ;
@@ -363,7 +393,7 @@ mod tests {
363393 schema : & pg_schema_cache:: SchemaCache :: new ( ) ,
364394 } ;
365395
366- let ctx = CompletionContext :: new ( & params) . await ;
396+ let ctx = CompletionContext :: new ( & params) ;
367397
368398 let node = ctx. ts_node . unwrap ( ) ;
369399
@@ -374,8 +404,8 @@ mod tests {
374404 ) ;
375405 }
376406
377- #[ tokio :: test]
378- async fn does_not_fail_with_empty_statements ( ) {
407+ #[ test]
408+ fn does_not_fail_with_empty_statements ( ) {
379409 let query = format ! ( "{}" , CURSOR_POS ) ;
380410
381411 let ( position, text) = get_text_and_position ( query. as_str ( ) ) ;
@@ -389,16 +419,16 @@ mod tests {
389419 schema : & pg_schema_cache:: SchemaCache :: new ( ) ,
390420 } ;
391421
392- let ctx = CompletionContext :: new ( & params) . await ;
422+ let ctx = CompletionContext :: new ( & params) ;
393423
394424 let node = ctx. ts_node . unwrap ( ) ;
395425
396426 assert_eq ! ( ctx. get_ts_node_content( node) , Some ( "" ) ) ;
397427 assert_eq ! ( ctx. wrapping_clause_type, None ) ;
398428 }
399429
400- #[ tokio :: test]
401- async fn does_not_fail_on_incomplete_keywords ( ) {
430+ #[ test]
431+ fn does_not_fail_on_incomplete_keywords ( ) {
402432 // Instead of autocompleting "FROM", we'll assume that the user
403433 // is selecting a certain column name, such as `frozen_account`.
404434 let query = format ! ( "select * fro{}" , CURSOR_POS ) ;
@@ -414,7 +444,7 @@ mod tests {
414444 schema : & pg_schema_cache:: SchemaCache :: new ( ) ,
415445 } ;
416446
417- let ctx = CompletionContext :: new ( & params) . await ;
447+ let ctx = CompletionContext :: new ( & params) ;
418448
419449 let node = ctx. ts_node . unwrap ( ) ;
420450
0 commit comments