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

Query 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.

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

Each list of values to send in a query must implement the trait ValueList.
By default this can be a slice &[], a tuple () (max 16 elements) of values to send, or a custom struct which derives from ValueList.

A few examples:

# extern crate scylla;
# use scylla::{Session, ValueList, frame::response::result::CqlValue};
# use std::error::Error;
# use std::collections::HashMap;
# async fn check_only_compiles(session: &Session) -> Result<(), Box<dyn Error>> {
// Empty slice means that there are no values to send
session.query("INSERT INTO ks.tab (a) VALUES(1)", &[]).await?;

// Empty tuple/unit also means that there are no values to send
session.query("INSERT INTO ks.tab (a) VALUES(1)", ()).await?;

// Sending three integers using a slice:
session
    .query("INSERT INTO ks.tab (a, b, c) VALUES(?, ?, ?)", [1_i32, 2, 3].as_ref())
    .await?;

// Sending an integer and a string using a tuple
session
    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", (2_i32, "Some text"))
    .await?;

// Sending an integer and a string using a named struct.
// The values will be passed in the order from the struct definition
#[derive(ValueList)]
struct IntString {
    first_col: i32,
    second_col: String,
}

let int_string = IntString {
    first_col: 42_i32,
    second_col: "hello".to_owned(),
};

session
    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", int_string)
    .await?;

// Sending a single value as a tuple requires a trailing coma (Rust syntax):
session.query("INSERT INTO ks.tab (a) VALUES(?)", (2_i32,)).await?;

// Each value can also be sent using a reference:
session
    .query("INSERT INTO ks.tab (a, b) VALUES(?, ?)", &(&2_i32, &"Some text"))
    .await?;

// A map of named values can also be provided:
let mut vals: HashMap<&str, CqlValue> = HashMap::new();
vals.insert("avalue", CqlValue::Text("hello".to_string()));
vals.insert("bvalue", CqlValue::Int(17));
session
    .query("INSERT INTO ks.tab (a, b) VALUES(:avalue, :bvalue)", &vals)
    .await?;

# Ok(())
# }

NULL values¶

Null values can be sent using Option<> - sending a None will make the value NULL:

# extern crate scylla;
# use scylla::Session;
# use std::error::Error;
# async fn check_only_compiles(session: &Session) -> Result<(), Box<dyn Error>> {
let null_i32: Option<i32> = None;
session
    .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,))
    .await?;
# Ok(())
# }

Unset values¶

When performing an insert with values which might be NULL, it’s better to use Unset.
Database treats inserting NULL as a delete operation and will generate a tombstone. Using Unset results in better performance:

# extern crate scylla;
# use scylla::Session;
# use std::error::Error;
# async fn check_only_compiles(session: &Session) -> Result<(), Box<dyn Error>> {
use scylla::frame::value::{MaybeUnset, Unset};

// Inserting a null results in suboptimal performance
let null_i32: Option<i32> = None;
session
    .query("INSERT INTO ks.tab (a) VALUES(?)", (null_i32,))
    .await?;

// Using MaybeUnset enum is better
let unset_i32: MaybeUnset<i32> = MaybeUnset::Unset;
session
    .query("INSERT INTO ks.tab (a) VALUES(?)", (unset_i32,))
    .await?;

// If we are sure that a value should be unset we can simply use Unset
session
    .query("INSERT INTO ks.tab (a) VALUES(?)", (Unset,))
    .await?;
# Ok(())
# }

See the issue for more information about Unset

Other data types¶

See Data Types for instructions on sending other data types

PREVIOUS
Simple query
NEXT
Query result
  • 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
  • Data Types
    • Bool, Tinyint, Smallint, Int, Bigint, Float, Double
    • Ascii, Text, Varchar
    • Counter
    • Blob
    • Inet
    • Uuid, Timeuuid
    • Date
    • Time
    • Timestamp
    • Decimal
    • Varint
    • List, Set, Map
    • Tuple
    • User defined types
  • Load balancing
    • Round robin
    • DC Aware Round robin
    • Token aware Round robin
    • Token aware DC Aware Round robin
  • Retry policy configuration
    • Fallthrough retry policy
    • Default retry policy
  • Speculative execution
    • Simple speculative execution
    • Percentile speculative execution
  • Driver metrics
  • Logging
  • Query tracing
    • Tracing a simple/prepared query
    • Tracing a batch query
    • Tracing a paged query
    • Tracing Session::prepare
  • Create an issue
  • Edit this page

On this page

  • Query values
    • NULL values
    • Unset values
    • Other data types
Logo
Docs Contact Us About Us
Mail List Icon Slack Icon
© 2022, ScyllaDB. All rights reserved.
Last updated on 06 May 2022.
Powered by Sphinx 4.3.2 & ScyllaDB Theme 1.2.1