ScyllaDB Documentation Logo Documentation
  • Server
    • ScyllaDB Open Source
    • ScyllaDB Enterprise
    • ScyllaDB Alternator
  • Cloud
  • Tools
    • ScyllaDB Manager
    • ScyllaDB Monitoring Stack
    • ScyllaDB Operator
  • Drivers
    • CQL Drivers
    • DynamoDB Drivers
Download
Menu
ScyllaDB Docs Scylla Rust Driver Making queries Query result

Query result¶

Session::query and Session::execute return a QueryResult with rows represented as Option<Vec<Row>>.

Basic representation¶

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("SELECT a from ks.tab", &[]).await?.rows {
    for row in rows {
        let int_value: i32 = row.columns[0].as_ref().unwrap().as_int().unwrap();
    }
}

Parsing using 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("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("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("SELECT a, b from ks.tab", &[]).await?.rows {
    for row in rows.into_typed::<(i32, String)>() {
        let (int_value, text_value): (i32, String) = row?;
    }
}

Parsing using convenience methods¶

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("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("SELECT a from ks.tab", &[])
    .await?
    .maybe_first_row_typed::<(i32,)>()?;

// no_rows fails when the response is rows
session.query("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("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?;
    }
}

Parsing row as a custom struct¶

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;

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("SELECT a, b from ks.tab", &[]).await?.rows {
    for row in rows.into_typed::<MyRow>() {
        let my_row: MyRow = row?;
    }
}

Other data types¶

For parsing other data types see Data Types

PREVIOUS
Query values
NEXT
Prepared query
Scylla Rust Driver
  • main
    • main
  • Scylla Rust Driver
  • Quick Start
    • Creating a project
    • Connecting and running a simple query
    • Running Scylla using Docker
  • Connecting to the cluster
    • Compression
    • Authentication
    • TLS
  • Making queries
    • Simple query
    • Query values
    • Query result
    • Prepared query
    • Batch statement
    • Paged query
    • USE keyspace
    • Schema agreement
    • Lightweight transaction (LWT) query
    • Query timeouts
  • Execution profiles
    • Creating a profile and setting it
    • All options supported by a profile
    • Priorities of execution settings
    • Remapping execution profile handles
  • Data Types
    • Bool, Tinyint, Smallint, Int, Bigint, Float, Double
    • Ascii, Text, Varchar
    • Counter
    • Blob
    • Inet
    • Uuid, Timeuuid
    • Date
    • Time
    • Timestamp
    • Duration
    • Decimal
    • Varint
    • List, Set, Map
    • Tuple
    • User defined types
  • Load balancing
    • DefaultPolicy
  • Retry policy configuration
    • Fallthrough retry policy
    • Default retry policy
    • Downgrading consistency retry policy
  • Speculative execution
    • Simple speculative execution
    • Percentile speculative execution
  • Driver metrics
  • Logging
  • Query tracing
    • Tracing a simple/prepared/batch query
    • Tracing a paged query
    • Tracing Session::prepare
    • Query Execution History
  • Schema
  • Create an issue
  • Edit this page

On this page

  • Query result
    • Basic representation
    • Parsing using into_typed
    • Parsing using convenience methods
      • NULL values
      • Parsing row as a custom struct
      • Other data types
Logo
Docs Contact Us About Us
Mail List Icon Slack Icon Forum Icon
© 2023, ScyllaDB. All rights reserved.
Last updated on 22 March 2023.
Powered by Sphinx 4.3.2 & ScyllaDB Theme 1.3.5