@@ -49,18 +49,24 @@ pub(crate) fn get_statement_for_completions(
49
49
if count == 1 {
50
50
eligible_statements. next ( )
51
51
} else {
52
- let mut prev_stmt = None ;
52
+ let mut prev_stmt: Option < ( StatementId , TextRange , String , Arc < tree_sitter :: Tree > ) > = None ;
53
53
54
54
for current_stmt in eligible_statements {
55
55
/*
56
56
* If we have multiple statements, we want to make sure that we do not overlap
57
57
* with the next one.
58
58
*
59
59
* select 1 |select 1;
60
+ *
61
+ * This is however ok if the current statement is a child of the previous one,
62
+ * such as in CREATE FUNCTION bodies.
60
63
*/
61
- if prev_stmt. is_some_and ( |_| current_stmt. 1 . contains ( position) ) {
64
+ if prev_stmt. is_some_and ( |prev| {
65
+ current_stmt. 1 . contains ( position) && !current_stmt. 0 . is_child_of ( & prev. 0 )
66
+ } ) {
62
67
return None ;
63
68
}
69
+
64
70
prev_stmt = Some ( current_stmt)
65
71
}
66
72
@@ -162,6 +168,30 @@ mod tests {
162
168
assert_eq ! ( text, "select * from" )
163
169
}
164
170
171
+ #[ test]
172
+ fn identifies_nested_stmts ( ) {
173
+ let sql = format ! (
174
+ r#"
175
+ create or replace function one()
176
+ returns integer
177
+ language sql
178
+ as $$
179
+ select {} from cool;
180
+ $$;
181
+ "# ,
182
+ CURSOR_POSITION
183
+ ) ;
184
+
185
+ let sql = sql. trim ( ) ;
186
+
187
+ let ( doc, position) = get_doc_and_pos ( sql) ;
188
+
189
+ let ( _, _, text, _) =
190
+ get_statement_for_completions ( & doc, position) . expect ( "Expected Statement" ) ;
191
+
192
+ assert_eq ! ( text. trim( ) , "select from cool;" )
193
+ }
194
+
165
195
#[ test]
166
196
fn does_not_consider_too_far_offset ( ) {
167
197
let sql = format ! ( "select * from {}" , CURSOR_POSITION ) ;
0 commit comments