NEW  New: cqlint (lint + format), cql-migrate and cqlprof → see the benchmarks

cqlc

A static CQL analyzer and Rust code generator for Cassandra-compatible databases, in the spirit of sqlc. Schema-first, offline, deterministic.

Write CQL, get typed Rust

-- schema/schema.cql
CREATE TABLE users_by_id (
    user_id uuid PRIMARY KEY,
    username text,
    email text,
    created_at timestamp
);

-- queries/users.cql
-- name: GetUserById :one
SELECT user_id, username, email, created_at
FROM users_by_id
WHERE user_id = ?;
let user: Option<GetUserByIdRow> = queries.get_user_by_id(user_id).await?;
// user.username: Option<String>   (regular columns may be absent)
// user.user_id:  Uuid             (primary key columns never are)
cargo install cqlc
cqlc init        # cqlc.toml, schema/schema.cql, queries/users.cql
cqlc generate    # writes src/queries.rs

cqlc is not a driver, an ORM, a query builder or a migration tool. It needs no database connection to generate code.

What it catches

Build-time errors

Unknown tables and columns, literals that do not fit the type, writes that miss the primary key, ranges on partition keys, UDT fields that do not exist. Each diagnostic has a stable code, a location and a hint.

Cassandra-aware warnings

Queries that do not restrict the partition key (CQL201), use ALLOW FILTERING (CQL202), restrict non-key columns (CQL203), skip a clustering column (CQL204) or order against the clustering order (CQL205).

Exact types

Null and absent values stay separate. UDTs become structs, lightweight transactions return an applied outcome, large results stream.

Deterministic and offline

Same input, same output. CI verifies it with cqlc generate --check and cqlc check --deny-warnings.

Cassandra 4.0, 4.1 and 5.0

Current Cassandra CQL, checked offline

cqlc 1.1 understands the CQL that real Cassandra projects use today. The reference is the ANTLR grammar and the native function classes of apache/cassandra (branches 4.0, 4.1, 5.0 and trunk), and the generated code runs against a real Cassandra 5.0 in CI.

VersionWhat cqlc covers
3.xthe complete data-plane subset: tables, UDTs, collections, counters, LWT, token(), tuple relations
4.0 / 4.1arithmetic (+ - * / %) with Cassandra's result types, duration literals (1d, 3h30m), ALTER/DROP, materialized views, user-defined functions and aggregates
5.0vector<float, N> (generated as Vec<f32>), ORDER BY … ANN OF vector search, SAI indexes and their restriction rules, similarity_*, maxwritetime, math and collection functions, MASKED WITH
6.0 (alpha)CHECK constraints parsed; transactions not yet
-- schema
CREATE TABLE products (id uuid PRIMARY KEY, name text, price double, embedding vector<float, 3>);
CREATE INDEX ON products (embedding) USING 'sai';

-- name: SimilarProducts :many
SELECT id, name, similarity_cosine(embedding, ?) AS score
FROM products ORDER BY embedding ANN OF ? LIMIT 3;

cqlc enforces the rules Cassandra enforces: an ANN OF query needs a SAI index on a vector column and a LIMIT of at most 1000; timestamp - timestamp does not exist and is an error. Not yet: BEGIN BATCH, Cassandra 6.0 transactions and named bind markers.

In the family

The cqlc-core crate (lexer, parser, schema resolver, type checker, typed IR) is the shared foundation of the family. cqlx verifies its generated DDL with it; cql-ai uses its lexer as a tokenizer and its analyzer to label training data. Front-end speed is on the benchmarks page.