Was this page helpful?
Caution
You're viewing documentation for an unstable version of Scylla Rust Driver. Switch to the latest stable version.
Session::query_unpaged
, Session::query_single_page
, Session::execute_unpaged
and Session::execute_single_page
return a QueryResult
with rows represented as Option<Vec<Row>>
.
Note
Using unpaged queries for SELECTs is discouraged in general. Query results may be so big that it is not preferable to fetch them all at once. Even with small results, if there are a lot of tombstones, then there can be similar bad consequences. However,query_unpaged
will return all results in one, possibly giant, piece (unless a timeout occurs due to high load incurred by the cluster). This:
increases latency,
has large memory footprint,
puts high load on the cluster,
is more likely to time out (because big work takes more time than little work, and returning one large piece of data is more work than returning one chunk of data).
To sum up, for SELECTs (especially those that may return a lot of data) prefer paged queries, e.g. with
Session::query_iter()
(see Paged queries).
Row
is a basic representation of a received row. It can be used by itself, but it’s a bit awkward to use:
if let Some(rows) = session.query_unpaged("SELECT a from ks.tab", &[]).await?.rows {
for row in rows {
let int_value: i32 = row.columns[0].as_ref().unwrap().as_int().unwrap();
}
}
into_typed
¶The driver provides a way to parse a row as a tuple of Rust types:
use scylla::IntoTypedRows;
// Parse row as a single column containing an int value
if let Some(rows) = session.query_unpaged("SELECT a from ks.tab", &[]).await?.rows {
for row in rows {
let (int_value,): (i32,) = row.into_typed::<(i32,)>()?;
}
}
// rows.into_typed() converts a Vec of Rows to an iterator of parsing results
if let Some(rows) = session.query_unpaged("SELECT a from ks.tab", &[]).await?.rows {
for row in rows.into_typed::<(i32,)>() {
let (int_value,): (i32,) = row?;
}
}
// Parse row as two columns containing an int and text columns
if let Some(rows) = session.query_unpaged("SELECT a, b from ks.tab", &[]).await?.rows {
for row in rows.into_typed::<(i32, String)>() {
let (int_value, text_value): (i32, String) = row?;
}
}
QueryResult
provides convenience methods for parsing rows.
Here are a few of them:
rows_typed::<RowT>()
- returns the rows parsed as the given type
maybe_first_row_typed::<RowT>
- returns Option<RowT>
containing first row from the result
first_row_typed::<RowT>
- same as maybe_first_row
, but fails without the first row
single_row_typed::<RowT>
- same as first_row
, but fails when there is more than one row
result_not_rows()
- ensures that query response was not rows
, helps avoid bugs
// Parse row as a single column containing an int value
let rows = session
.query_unpaged("SELECT a from ks.tab", &[])
.await?
.rows_typed::<(i32,)>()?; // Same as .rows()?.into_typed()
for row in rows {
let (int_value,): (i32,) = row?;
}
// maybe_first_row_typed gets the first row and parses it as the given type
let first_int_val: Option<(i32,)> = session
.query_unpaged("SELECT a from ks.tab", &[])
.await?
.maybe_first_row_typed::<(i32,)>()?;
// no_rows fails when the response is rows
session.query_unpaged("INSERT INTO ks.tab (a) VALUES (0)", &[]).await?.result_not_rows()?;
For more see QueryResult
NULL
values¶NULL
values will return an error when parsed as a Rust type.
To properly handle NULL
values parse column as an Option<>
:
use scylla::IntoTypedRows;
// Parse row as two columns containing an int and text which might be null
if let Some(rows) = session.query_unpaged("SELECT a, b from ks.tab", &[]).await?.rows {
for row in rows.into_typed::<(i32, Option<String>)>() {
let (int_value, str_or_null): (i32, Option<String>) = row?;
}
}
It is possible to receive row as a struct with fields matching the columns.
The struct must:
have the same number of fields as the number of queried columns
have field types matching the columns being received
derive FromRow
Field names don’t need to match column names.
use scylla::IntoTypedRows;
use scylla::macros::FromRow;
use scylla::frame::response::cql_to_rust::FromRow;
#[derive(FromRow)]
struct MyRow {
age: i32,
name: Option<String>
}
// Parse row as two columns containing an int and text which might be null
if let Some(rows) = session.query_unpaged("SELECT a, b from ks.tab", &[]).await?.rows {
for row in rows.into_typed::<MyRow>() {
let my_row: MyRow = row?;
}
}
For parsing other data types see Data Types
Was this page helpful?