Skip to main content

Overview

The PreparedStatement struct represents a CQL statement that has been prepared on the server. Prepared statements offer significant performance and safety benefits over unprepared statements.

Benefits

  • Performance: Statement is parsed and planned only once on the server
  • Type Safety: Values are validated against metadata during serialization
  • Token-Aware Routing: Driver can compute partition tokens for optimal routing
  • Result Metadata Caching: Reduces network overhead

Cloning

Cloning a PreparedStatement is cheap - it only copies Arc pointers and small fields. Always prefer cloning over re-preparing. Source: scylla/src/statement/prepared.rs:202

Type Definition

pub struct PreparedStatement {
    pub prepare_tracing_ids: Vec<Uuid>,
    // ... internal fields
}

Creation

Prepared statements are created via Session::prepare:
let prepared = session.prepare("SELECT * FROM users WHERE id = ?").await?;

Metadata Access

get_id

Returns the prepared statement ID.
pub fn get_id(&self) -> &Bytes
id
&Bytes
Unique identifier assigned by the server

get_statement

Returns the original CQL statement text.
pub fn get_statement(&self) -> &str

get_variable_col_specs

Returns column specifications for bind variables.
pub fn get_variable_col_specs(&self) -> ColumnSpecs<'_, 'static>
specs
ColumnSpecs
Metadata about bind markers (name, type, table)

get_variable_pk_indexes

Returns partition key indexes in the bind variables.
pub fn get_variable_pk_indexes(&self) -> &[PartitionKeyIndex]
indexes
&[PartitionKeyIndex]
Positions and sequence of partition key columns

get_current_result_set_col_specs

Returns column specifications for the result set.
pub fn get_current_result_set_col_specs(&self) -> ColumnSpecsGuard
guard
ColumnSpecsGuard
Snapshot of current result metadata (may be updated by server)

get_prepare_tracing_ids

Returns tracing IDs from statement preparation.
pub fn get_prepare_tracing_ids(&self) -> &[Uuid]

Table Information

get_table_spec

Returns the keyspace and table this statement operates on.
pub fn get_table_spec(&self) -> Option<&TableSpec<'_>>

get_keyspace_name

pub fn get_keyspace_name(&self) -> Option<&str>

get_table_name

pub fn get_table_name(&self) -> Option<&str>

Token and Routing

is_token_aware

Returns true if the statement can be routed in a token-aware manner.
pub fn is_token_aware(&self) -> bool
aware
bool
true if partition key information is available

is_confirmed_lwt

Returns true if this is a confirmed lightweight transaction.
pub fn is_confirmed_lwt(&self) -> bool
lwt
bool
true if LWT optimization can be applied (ScyllaDB-specific)

calculate_token

Computes the partition token for given bound values.
pub fn calculate_token(
    &self,
    values: &impl SerializeRow
) -> Result<Option<Token>, PartitionKeyError>
values
&impl SerializeRow
required
Bound values containing partition key columns
token
Result<Option<Token>, PartitionKeyError>
Computed token, or None if statement is not token-aware
Example:
let prepared = session.prepare("SELECT * FROM users WHERE id = ?").await?;
let token = prepared.calculate_token(&(42,))?;
println!("Token: {:?}", token);

compute_partition_key

Computes the serialized partition key.
pub fn compute_partition_key(
    &self,
    bound_values: &impl SerializeRow
) -> Result<Bytes, PartitionKeyError>
bound_values
&impl SerializeRow
required
Values to serialize into partition key
key
Result<Bytes, PartitionKeyError>
Serialized partition key according to CQL protocol rules

get_partitioner_name

Returns the partitioner name used by the cluster.
pub fn get_partitioner_name(&self) -> &PartitionerName

Configuration Methods

Paging

set_page_size

pub fn set_page_size(&mut self, page_size: i32)
page_size
i32
required
Number of rows per page (must be positive)
Panics: If page_size is non-positive.

get_page_size

pub fn get_page_size(&self) -> i32

Consistency

set_consistency

pub fn set_consistency(&mut self, c: Consistency)

unset_consistency

pub fn unset_consistency(&mut self)

get_consistency

pub fn get_consistency(&self) -> Option<Consistency>

Serial Consistency

set_serial_consistency

pub fn set_serial_consistency(&mut self, sc: Option<SerialConsistency>)

unset_serial_consistency

pub fn unset_serial_consistency(&mut self)

get_serial_consistency

pub fn get_serial_consistency(&self) -> Option<SerialConsistency>

Idempotence

set_is_idempotent

pub fn set_is_idempotent(&mut self, is_idempotent: bool)

get_is_idempotent

pub fn get_is_idempotent(&self) -> bool

Tracing

set_tracing

pub fn set_tracing(&mut self, should_trace: bool)

get_tracing

pub fn get_tracing(&self) -> bool

Result Metadata Caching

set_use_cached_result_metadata

Controls whether to use cached result metadata.
pub fn set_use_cached_result_metadata(&mut self, use_cached_metadata: bool)
use_cached_metadata
bool
required
true to skip receiving metadata with each response
For databases without metadata ID extension support (Cassandra, older ScyllaDB), enabling this risks data corruption if schema changes. For modern ScyllaDB, this setting is ignored and caching is always used safely.

get_use_cached_result_metadata

pub fn get_use_cached_result_metadata(&self) -> bool

Timestamp

set_timestamp

pub fn set_timestamp(&mut self, timestamp: Option<i64>)

get_timestamp

pub fn get_timestamp(&self) -> Option<i64>

Timeout

set_request_timeout

pub fn set_request_timeout(&mut self, timeout: Option<Duration>)

get_request_timeout

pub fn get_request_timeout(&self) -> Option<Duration>

Policies

set_retry_policy

pub fn set_retry_policy(&mut self, retry_policy: Option<Arc<dyn RetryPolicy>>)

get_retry_policy

pub fn get_retry_policy(&self) -> Option<&Arc<dyn RetryPolicy>>

set_load_balancing_policy

pub fn set_load_balancing_policy(
    &mut self,
    load_balancing_policy: Option<Arc<dyn LoadBalancingPolicy>>
)

get_load_balancing_policy

pub fn get_load_balancing_policy(&self) -> Option<&Arc<dyn LoadBalancingPolicy>>

Execution Profile

set_execution_profile_handle

pub fn set_execution_profile_handle(
    &mut self,
    profile_handle: Option<ExecutionProfileHandle>
)

get_execution_profile_handle

pub fn get_execution_profile_handle(&self) -> Option<&ExecutionProfileHandle>

History Listener

set_history_listener

pub fn set_history_listener(&mut self, history_listener: Arc<dyn HistoryListener>)

remove_history_listener

pub fn remove_history_listener(&mut self) -> Option<Arc<dyn HistoryListener>>

Example Usage

use scylla::{Session, SessionBuilder};
use scylla::frame::types::Consistency;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let session = SessionBuilder::new()
        .known_node("127.0.0.1:9042")
        .build()
        .await?;

    // Prepare a statement
    let mut prepared = session
        .prepare("INSERT INTO my_keyspace.users (id, name, email) VALUES (?, ?, ?)")
        .await?;

    // Configure the statement
    prepared.set_consistency(Consistency::Quorum);
    prepared.set_is_idempotent(true);

    // Execute with values
    session.execute_unpaged(&prepared, (1, "Alice", "[email protected]")).await?;

    // The same prepared statement can be reused
    session.execute_unpaged(&prepared, (2, "Bob", "[email protected]")).await?;

    // Check if token-aware routing is possible
    if prepared.is_token_aware() {
        let token = prepared.calculate_token(&(1,))?;
        println!("Computed token: {:?}", token);
    }

    Ok(())
}

Schema Changes and Repreparation

The driver automatically handles statement repreparation when the server invalidates cached statements due to schema changes.

When to Re-Prepare

You should drop and re-prepare a statement when:
  1. Bind marker UDT changes: Adding fields to a UDT that is a bind marker
  2. Column type changes: Dropping and re-adding a bind marker column with different type (ScyllaDB-specific)
Result metadata is automatically updated in CQL v5 or with ScyllaDB’s metadata ID extension.

See Also

Build docs developers (and LLMs) love