11# Paged query
2- Sometimes query results might not fit in a single page. Paged queries
3- allow to receive the whole result page by page.
2+ Sometimes query results might be so big that one prefers not to fetch them all at once,
3+ e.g. to reduce latency and/or memory footprint.
4+ Paged queries allow to receive the whole result page by page, with a configurable page size.
45
5- ` Session::query_iter ` and ` Session::execute_iter ` take a [ simple query] ( simple.md ) or a [ prepared query ] ( prepared.md )
6- and return an ` async ` iterator over result ` Rows ` .
6+ ` Session::query_iter ` and ` Session::execute_iter ` take a [ simple query] ( simple.md )
7+ or a [ prepared query ] ( prepared.md ) and return an ` async ` iterator over result ` Rows ` .
78
89> *** Warning*** \
910> In case of unprepared variant (` Session::query_iter ` ) if the values are not empty
@@ -79,7 +80,7 @@ On a `Query`:
7980use scylla :: query :: Query ;
8081
8182let mut query : Query = Query :: new (" SELECT a, b FROM ks.t" );
82- query . set_page_size (16 );
83+ query . set_page_size (16. try_into () . unwrap () );
8384
8485let _ = session . query_iter (query , & []). await ? ; // ...
8586# Ok (())
@@ -98,7 +99,7 @@ let mut prepared: PreparedStatement = session
9899 . prepare (" SELECT a, b FROM ks.t" )
99100 . await ? ;
100101
101- prepared . set_page_size (16 );
102+ prepared . set_page_size (16. try_into () . unwrap () );
102103
103104let _ = session . execute_iter (prepared , & []). await ? ; // ...
104105# Ok (())
@@ -117,12 +118,33 @@ On a `Query`:
117118# use std :: error :: Error ;
118119# async fn check_only_compiles (session : & Session ) -> Result <(), Box <dyn Error >> {
119120use scylla :: query :: Query ;
121+ use scylla :: statement :: {PagingState , PagingStateResponse };
122+ use std :: ops :: ControlFlow ;
123+
124+ let paged_query = Query :: new (" SELECT a, b, c FROM ks.t" ). with_page_size (6. try_into (). unwrap ());
125+
126+ let mut paging_state = PagingState :: start ();
127+ loop {
128+ let (res , paging_state_response ) = session
129+ . query_single_page (paged_query . clone (), & [], paging_state )
130+ . await ? ;
131+
132+ // Do something with `res`.
133+ // ...
134+
135+ match paging_state_response . into_paging_control_flow () {
136+ ControlFlow :: Break (()) => {
137+ // No more pages to be fetched.
138+ break ;
139+ }
140+ ControlFlow :: Continue (new_paging_state ) => {
141+ // Update paging state from the response, so that query
142+ // will be resumed from where it ended the last time.
143+ paging_state = new_paging_state
144+ }
145+ }
146+ }
120147
121- let paged_query = Query :: new (" SELECT a, b, c FROM ks.t" ). with_page_size (6 );
122- let res1 = session . query (paged_query . clone (), & []). await ? ;
123- let res2 = session
124- . query_single_page (paged_query . clone (), & [], res1 . paging_state)
125- . await ? ;
126148# Ok (())
127149# }
128150```
@@ -139,14 +161,37 @@ On a `PreparedStatement`:
139161# use std :: error :: Error ;
140162# async fn check_only_compiles (session : & Session ) -> Result <(), Box <dyn Error >> {
141163use scylla :: query :: Query ;
164+ use scylla :: statement :: {PagingState , PagingStateResponse };
165+ use std :: ops :: ControlFlow ;
142166
143167let paged_prepared = session
144- . prepare (Query :: new (" SELECT a, b, c FROM ks.t" ). with_page_size (7 ))
145- . await ? ;
146- let res1 = session . execute (& paged_prepared , & []). await ? ;
147- let res2 = session
148- . execute_single_page (& paged_prepared , & [], res1 . paging_state)
168+ . prepare (Query :: new (" SELECT a, b, c FROM ks.t" ). with_page_size (7. try_into (). unwrap ()))
149169 . await ? ;
170+
171+ let mut paging_state = PagingState :: start ();
172+ loop {
173+ let (res , paging_state_response ) = session
174+ . execute_single_page (& paged_prepared , & [], paging_state )
175+ . await ? ;
176+
177+ println! (
178+ " Paging state response from the prepared statement execution: {:#?} ({} rows)" ,
179+ paging_state_response ,
180+ res . rows_num ()? ,
181+ );
182+
183+ match paging_state_response . into_paging_control_flow () {
184+ ControlFlow :: Break (()) => {
185+ // No more pages to be fetched.
186+ break ;
187+ }
188+ ControlFlow :: Continue (new_paging_state ) => {
189+ // Update paging state from the response, so that query
190+ // will be resumed from where it ended the last time.
191+ paging_state = new_paging_state
192+ }
193+ }
194+ }
150195# Ok (())
151196# }
152197```
0 commit comments