Simple query

Simple query takes query text and values and simply executes them on a Session:


#![allow(unused)]
fn main() {
extern crate scylla;
use scylla::Session;
use std::error::Error;
async fn simple_query_example(session: &Session) -> Result<(), Box<dyn Error>> {
// Insert a value into the table
let to_insert: i32 = 12345;
session
    .query("INSERT INTO keyspace.table (a) VALUES(?)", (to_insert,))
    .await?;
Ok(())
}
}

Warning
Don't use simple query to receive large amounts of data.
By default the query is unpaged and might cause heavy load on the cluster.
In such cases set a page size and use paged query instead.

When page size is set, query will return only the first page of results.

First argument - the query

As the first argument Session::query takes anything implementing Into<Query>.
You can create a query manually to set custom options. For example to change query consistency:


#![allow(unused)]
fn main() {
extern crate scylla;
use scylla::Session;
use std::error::Error;
async fn check_only_compiles(session: &Session) -> Result<(), Box<dyn Error>> {
use scylla::query::Query;
use scylla::statement::Consistency;

// Create a Query manually to change the Consistency to ONE
let mut my_query: Query = Query::new("INSERT INTO ks.tab (a) VALUES(?)");
my_query.set_consistency(Consistency::One);

// Insert a value into the table
let to_insert: i32 = 12345;
session.query(my_query, (to_insert,)).await?;
Ok(())
}
}

See Query API documentation for more options

Second argument - the values

Query text is constant, but the values might change. You can pass changing values to a query by specifying a list of variables as bound values.
Each ? in query text will be filled with the matching value.

The easiest way is to pass values using a tuple:


#![allow(unused)]
fn main() {
extern crate scylla;
use scylla::Session;
use std::error::Error;
async fn check_only_compiles(session: &Session) -> Result<(), Box<dyn Error>> {
// Sending an integer and a string using a tuple
session
    .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, 'text2')", (2_i32, "Some text"))
    .await?;
Ok(())
}
}

Here the first ? will be filled with 2 and the second with "Some text".

Never pass values by adding strings, this could lead to SQL Injection

See Query values for more information about sending values in queries

Query result

Session::query returns QueryResult with rows represented as Option<Vec<Row>>.
Each row can be parsed as a tuple of rust types using into_typed:


#![allow(unused)]
fn main() {
extern crate scylla;
use scylla::Session;
use std::error::Error;
async fn check_only_compiles(session: &Session) -> Result<(), Box<dyn Error>> {
use scylla::IntoTypedRows;

// Query rows from the table and print them
if let Some(rows) = session.query("SELECT a FROM ks.tab", &[]).await?.rows {
    // Parse each row as a tuple containing single i32
    for row in rows.into_typed::<(i32,)>() {
        let read_row: (i32,) = row?;
        println!("Read a value from row: {}", read_row.0);
    }
}
Ok(())
}
}

In cases where page size is set, simple query returns only a single page of results.
To receive all pages use a paged query instead.

See Query result for more information about handling query results

Performance

Simple queries should not be used in places where performance matters.
If perfomance matters use a Prepared query instead.

With simple query the database has to parse query text each time it's executed, which worsens performance.

Additionaly token and shard aware load balancing does not work with simple queries. They are sent to random nodes.