Skip to main content

Overview

This page documents the mapping between CQL (Cassandra Query Language) data types and Rust types in the ScyllaDB Rust Driver.

Type Mapping Table

CQL TypeRust Type(s)Notes
booleanbool
tinyinti8
smallinti16
inti32
biginti64
floatf32IEEE-754 32-bit
doublef64IEEE-754 64-bit
varintCqlVarint, CqlVarintBorrowed<'_>, num_bigint::BigIntRequires feature flag for BigInt
decimalCqlDecimal, CqlDecimalBorrowed<'_>, bigdecimal_04::BigDecimalRequires feature flag for BigDecimal
ascii&str, StringASCII-only string
text / varchar&str, StringUTF-8 string
blob&[u8], Vec<u8>, BytesBinary data
uuiduuid::UuidAny UUID version
timeuuidCqlTimeuuidUUID v1 with special ordering
inetstd::net::IpAddrIPv4 or IPv6
dateCqlDate, chrono::NaiveDate, time::DateDays since epoch
timeCqlTime, chrono::NaiveTime, time::TimeNanoseconds since midnight
timestampCqlTimestamp, chrono::DateTime<Utc>, time::OffsetDateTimeMilliseconds since Unix epoch
durationCqlDurationMonths, days, nanoseconds
counterCounterSpecial counter type
list<T>Vec<T>Ordered collection
set<T>Vec<T>, HashSet<T>, BTreeSet<T>Unordered unique values
map<K, V>HashMap<K, V>, BTreeMap<K, V>Key-value pairs
vector<T, N>Vec<T>Fixed-size vector (N elements)
tuple<T1, T2, ...>(T1, T2, ...)Fixed-size heterogeneous collection
User-Defined TypeStruct with #[derive(SerializeValue)] or #[derive(DeserializeValue)]Custom types

Numeric Types

Fixed-Size Integers

// CQL: tinyint, smallint, int, bigint
let tiny: i8 = -128;
let small: i16 = -32768;
let normal: i32 = -2147483648;
let big: i64 = -9223372036854775808;

Floating Point

// CQL: float, double
let f: f32 = 3.14;
let d: f64 = 2.718281828;

Arbitrary Precision

Varint

use scylla::value::CqlVarint;

// Native implementation
let varint = CqlVarint::from_signed_bytes_be_slice(&[0x01, 0x02, 0x03]);

// With num-bigint-03 feature
#[cfg(feature = "num-bigint-03")]
use num_bigint_03::BigInt;
#[cfg(feature = "num-bigint-03")]
let bigint = BigInt::from(12345);

// With num-bigint-04 feature
#[cfg(feature = "num-bigint-04")]
use num_bigint_04::BigInt;
#[cfg(feature = "num-bigint-04")]
let bigint = BigInt::from(12345);

Decimal

use scylla::value::CqlDecimal;

// Native implementation
let decimal = CqlDecimal::from_signed_be_bytes_slice_and_exponent(&[0x01], 2);

// With bigdecimal-04 feature
#[cfg(feature = "bigdecimal-04")]
use bigdecimal_04::BigDecimal;
#[cfg(feature = "bigdecimal-04")]
let decimal = BigDecimal::from(123.45);

Counter

use scylla::value::Counter;

let counter = Counter(42);
Counters can only be updated with UPDATE statements, not INSERT.

String Types

Text (UTF-8)

// CQL: text, varchar
let borrowed: &str = "Hello, World!";
let owned: String = "Hello, World!".to_string();

ASCII

// CQL: ascii
let ascii: String = "ASCII only".to_string();
The driver validates that ASCII values only contain ASCII characters during serialization.

Binary Type

// CQL: blob
let borrowed: &[u8] = &[0x01, 0x02, 0x03];
let owned: Vec<u8> = vec![0x01, 0x02, 0x03];

// With bytes crate
use bytes::Bytes;
let bytes = Bytes::from_static(&[0x01, 0x02, 0x03]);

UUID Types

UUID

use uuid::Uuid;

// CQL: uuid
let id = Uuid::new_v4();
let parsed = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")?;

Timeuuid

use scylla::value::CqlTimeuuid;
use uuid::Uuid;

// CQL: timeuuid
let timeuuid = CqlTimeuuid::from(Uuid::now_v1(&[/* node */]));
CqlTimeuuid uses special comparison logic that follows ScyllaDB/Cassandra semantics for timeuuid ordering.

Date and Time Types

Date

use scylla::value::CqlDate;

// Native type: days since -5877641-06-23
let date = CqlDate(2_u32.pow(31));

// With chrono-04 feature
#[cfg(feature = "chrono-04")]
use chrono::NaiveDate;
#[cfg(feature = "chrono-04")]
let date = NaiveDate::from_ymd_opt(2024, 1, 1).unwrap();

// With time-03 feature
#[cfg(feature = "time-03")]
use time::Date;
#[cfg(feature = "time-03")]
let date = Date::from_calendar_date(2024, time::Month::January, 1)?;

Time

use scylla::value::CqlTime;

// Native type: nanoseconds since midnight
let time = CqlTime(3600_000_000_000);

// With chrono-04 feature
#[cfg(feature = "chrono-04")]
use chrono::NaiveTime;
#[cfg(feature = "chrono-04")]
let time = NaiveTime::from_hms_opt(12, 0, 0).unwrap();

// With time-03 feature
#[cfg(feature = "time-03")]
use time::Time;
#[cfg(feature = "time-03")]
let time = Time::from_hms(12, 0, 0)?;

Timestamp

use scylla::value::CqlTimestamp;

// Native type: milliseconds since Unix epoch
let timestamp = CqlTimestamp(1234567890000);

// With chrono-04 feature
#[cfg(feature = "chrono-04")]
use chrono::{DateTime, Utc};
#[cfg(feature = "chrono-04")]
let timestamp = Utc::now();

// With time-03 feature
#[cfg(feature = "time-03")]
use time::OffsetDateTime;
#[cfg(feature = "time-03")]
let timestamp = OffsetDateTime::now_utc();

Duration

use scylla::value::CqlDuration;

// CQL: duration
let duration = CqlDuration {
    months: 1,
    days: 2,
    nanoseconds: 3_000_000_000,
};

Network Type

use std::net::IpAddr;

// CQL: inet
let ipv4: IpAddr = "127.0.0.1".parse()?;
let ipv6: IpAddr = "::1".parse()?;

Collection Types

List

// CQL: list<int>
let numbers: Vec<i32> = vec![1, 2, 3, 4, 5];

Set

use std::collections::HashSet;

// CQL: set<text>
let mut tags = HashSet::new();
tags.insert("rust".to_string());
tags.insert("scylla".to_string());

// Can also use Vec or BTreeSet
let tags_vec: Vec<String> = vec!["rust".to_string(), "scylla".to_string()];

Map

use std::collections::HashMap;

// CQL: map<text, int>
let mut scores = HashMap::new();
scores.insert("Alice".to_string(), 100);
scores.insert("Bob".to_string(), 95);

// Can also use BTreeMap
use std::collections::BTreeMap;
let scores_btree: BTreeMap<String, i32> = BTreeMap::new();

Vector (Fixed-Size)

// CQL: vector<float, 3>
let embedding: Vec<f32> = vec![0.1, 0.2, 0.3];
The length must match the declared size in the CQL type.

Tuple

// CQL: tuple<int, text, boolean>
let data: (i32, String, bool) = (42, "hello".to_string(), true);

// Nested tuples
let nested: (i32, (String, bool)) = (42, ("hello".to_string(), true));

User-Defined Types

use scylla::macros::{SerializeValue, DeserializeValue};

// CQL:
// CREATE TYPE address (
//     street text,
//     city text,
//     zip int
// );

#[derive(SerializeValue, DeserializeValue, Debug)]
struct Address {
    street: String,
    city: String,
    zip: i32,
}

let addr = Address {
    street: "123 Main St".to_string(),
    city: "Springfield".to_string(),
    zip: 12345,
};

NULL and Empty Values

NULL

// Use Option<T> for nullable columns
let maybe_email: Option<String> = None;  // NULL
let email: Option<String> = Some("[email protected]".to_string());  // Not NULL

Unset

use scylla::value::{Unset, MaybeUnset};

// Unset value (doesn't update the column)
let unset_field = Unset;

// Maybe unset
let field = MaybeUnset::Set(42);
let unchanged = MaybeUnset::<i32>::Unset;

Empty

use scylla::value::MaybeEmpty;

// For emptiable types (numeric types, etc.)
let empty = MaybeEmpty::<i32>::Empty;
let value = MaybeEmpty::Value(42);

Feature Flags

Date/Time Features

[dependencies]
scylla = { version = "*", features = ["chrono-04"] }
# or
scylla = { version = "*", features = ["time-03"] }

BigInt Features

[dependencies]
scylla = { version = "*", features = ["num-bigint-03"] }
# or
scylla = { version = "*", features = ["num-bigint-04"] }

BigDecimal Features

[dependencies]
scylla = { version = "*", features = ["bigdecimal-04"] }

Secrecy Features

[dependencies]
scylla = { version = "*", features = ["secrecy-08"] }
# or
scylla = { version = "*", features = ["secrecy-10"] }

Type Conversion Examples

Serialization

use scylla::serialize::value::SerializeValue;

// Primitive to CQL
let value: i32 = 42;
// Serializes to CQL int

// Collection to CQL
let list = vec![1, 2, 3];
// Serializes to CQL list<int>

// Struct to CQL UDT
#[derive(SerializeValue)]
struct MyType { field: i32 }
// Serializes to CQL UDT

Deserialization

use scylla::deserialize::value::DeserializeValue;

// CQL int to Rust
let value: i32 = // ... from CQL int

// CQL list<int> to Rust
let list: Vec<i32> = // ... from CQL list<int>

// CQL UDT to Rust struct
#[derive(DeserializeValue)]
struct MyType { field: i32 }
let my_val: MyType = // ... from CQL UDT

See Also

Build docs developers (and LLMs) love