@@ -66,6 +66,18 @@ pub struct CompletionItem {
6666 pub detail : Option < String > ,
6767}
6868
69+ /// A single SQL statement extracted from a multi-statement source.
70+ #[ derive( Debug , Serialize , Deserialize ) ]
71+ #[ serde( rename_all = "camelCase" ) ]
72+ pub struct Statement {
73+ /// The SQL text of the statement
74+ pub sql : String ,
75+ /// Start byte offset in the original SQL string
76+ pub start : u32 ,
77+ /// End byte offset in the original SQL string
78+ pub end : u32 ,
79+ }
80+
6981/// In-memory file system for storing SQL files.
7082///
7183/// This wraps `pgls_fs::MemoryFileSystem` with a simpler API
@@ -367,6 +379,22 @@ impl Workspace {
367379 Err ( e) => vec ! [ e. to_string( ) ] ,
368380 }
369381 }
382+
383+ /// Split SQL into individual statements.
384+ ///
385+ /// Each returned `Statement` contains the SQL text and its byte offsets
386+ /// in the original string.
387+ pub fn split_statements ( & self , sql : & str ) -> Vec < Statement > {
388+ self . inner
389+ . split_statements ( sql)
390+ . into_iter ( )
391+ . map ( |range| Statement {
392+ sql : sql[ range] . to_string ( ) ,
393+ start : u32:: from ( range. start ( ) ) ,
394+ end : u32:: from ( range. end ( ) ) ,
395+ } )
396+ . collect ( )
397+ }
370398}
371399
372400#[ cfg( test) ]
@@ -397,6 +425,30 @@ mod tests {
397425 assert ! ( !errors. is_empty( ) ) ;
398426 }
399427
428+ #[ test]
429+ fn test_workspace_split_statements ( ) {
430+ let workspace = Workspace :: new ( ) ;
431+
432+ let statements = workspace. split_statements ( "SELECT 1; SELECT 2;" ) ;
433+ assert_eq ! ( statements. len( ) , 2 ) ;
434+ assert_eq ! ( statements[ 0 ] . sql, "SELECT 1;" ) ;
435+ assert_eq ! ( statements[ 0 ] . start, 0 ) ;
436+ assert_eq ! ( statements[ 0 ] . end, 9 ) ;
437+ assert_eq ! ( statements[ 1 ] . sql, "SELECT 2;" ) ;
438+ assert_eq ! ( statements[ 1 ] . start, 10 ) ;
439+ assert_eq ! ( statements[ 1 ] . end, 19 ) ;
440+ }
441+
442+ #[ test]
443+ fn test_workspace_split_statements_ignores_comments ( ) {
444+ let workspace = Workspace :: new ( ) ;
445+
446+ let statements = workspace. split_statements ( "-- comment\n SELECT 1;\n \n SELECT 2;" ) ;
447+ assert_eq ! ( statements. len( ) , 2 ) ;
448+ assert_eq ! ( statements[ 0 ] . sql, "SELECT 1;" ) ;
449+ assert_eq ! ( statements[ 1 ] . sql, "SELECT 2;" ) ;
450+ }
451+
400452 #[ test]
401453 fn test_memory_fs ( ) {
402454 let mut fs = MemoryFs :: new ( ) ;
0 commit comments