← Back to homepage

CQL Reference

Ferrosa implements CQL native protocol v5. This page documents what's supported, what's different, and what Ferrosa adds on top.

Beta: Ferrosa is currently in beta. CQL compatibility is under active development.

On this page

Protocol

Wire protocol

Ferrosa implements CQL native protocol version 5 with the standard 9-byte frame header. All 16 opcodes are handled:

OpcodeNameDirection
0x00ERRORResponse
0x01STARTUPRequest
0x02READYResponse
0x03AUTHENTICATEResponse
0x05OPTIONSRequest
0x06SUPPORTEDResponse
0x07QUERYRequest
0x08RESULTResponse
0x09PREPARERequest
0x0AEXECUTERequest
0x0BREGISTERRequest
0x0CEVENTResponse
0x0DBATCHRequest
0x0EAUTH_CHALLENGEResponse
0x0FAUTH_RESPONSERequest
0x10AUTH_SUCCESSResponse

Compression

Frame-level compression is negotiated during STARTUP via the COMPRESSION option:

Compression is optional. Uncompressed frames are always accepted.

Authentication

SASL PLAIN authentication via the standard org.apache.cassandra.auth.PasswordAuthenticator flow. Passwords are hashed with bcrypt or argon2. Disable with FERROSA_AUTH_DISABLED=true for development.

Data Types

CQL TypeProtocol IDStatus
ascii0x0001Supported
bigint0x0002Supported
blob0x0003Supported
boolean0x0004Supported
counter0x0005Supported
decimal0x0006Supported
double0x0007Supported
float0x0008Supported
int0x0009Supported
timestamp0x000BSupported
uuid0x000CSupported
varchar / text0x000DSupported
varint0x000ESupported
timeuuid0x000FSupported
inet0x0010Supported
date0x0011Supported
time0x0012Supported
smallint0x0013Supported
tinyint0x0014Supported
list<T>0x0020Supported
map<K, V>0x0021Supported
set<T>0x0022Supported
tuple<...>0x0031Supported
frozen<T>Supported
duration0x0015Supported
UDT0x0030Supported

DDL Statements

StatementStatusNotes
CREATE KEYSPACESupportedWITH replication, IF NOT EXISTS, DURABLE_WRITES
ALTER KEYSPACESupportedChange replication, durable_writes
DROP KEYSPACESupportedIF EXISTS
CREATE TABLESupportedPartition key, clustering key with order, IF NOT EXISTS, table options
ALTER TABLESupportedADD column, DROP column
DROP TABLESupportedIF EXISTS
CREATE INDEXSupportedUSING type, WITH OPTIONS, IF NOT EXISTS — see below
DROP INDEXSupportedIF EXISTS
CREATE MATERIALIZED VIEWNot yet
CREATE TYPE (UDT)SupportedCREATE TYPE, ALTER TYPE, DROP TYPE — full UDT DDL lifecycle
CREATE FUNCTION / AGGREGATESupportedCREATE/DROP FUNCTION (WASM), CREATE/DROP AGGREGATE — full DDL lifecycle with cluster replication

Example

CREATE KEYSPACE social WITH replication = {
  'class': 'SimpleStrategy',
  'replication_factor': 3
} AND durable_writes = true;

CREATE TABLE social.users (
  user_id uuid,
  name text,
  email text,
  created_at timestamp,
  tags set<text>,
  PRIMARY KEY (user_id)
);

DML Statements

StatementStatusNotes
SELECTSupportedWHERE, ORDER BY, LIMIT, bind markers (?), named bind markers (:name), IN clause
INSERTSupportedIF NOT EXISTS, USING TTL, USING TIMESTAMP
UPDATESupportedSET, WHERE, IF conditions
DELETESupportedWHERE, IF EXISTS, column-level delete
BATCHSupportedBEGIN BATCH ... APPLY BATCH (unlogged)
TRUNCATESupported
USESupportedSet default keyspace for session

Prepared statements

Full PREPARE/EXECUTE support. The prepared statement cache uses moka with W-TinyLFU eviction (64 MB default). Bind markers (?) and named bind markers (:name) are both supported.

-- Prepare
PREPARE stmt FROM 'SELECT * FROM social.users WHERE user_id = ?';

-- Execute with positional bind
EXECUTE stmt USING 550e8400-e29b-41d4-a716-446655440000;

Comparison operators

WHERE clauses support: =, <, >, <=, >=, !=, IN

Consistency levels

Ferrosa supports the following consistency levels for reads and writes:

Set per-query via the standard CQL protocol flags, or configure a default with FERROSA_DEFAULT_CL (default: QUORUM).

Auth & Roles

StatementStatusNotes
CREATE ROLESupportedWITH PASSWORD, SUPERUSER, LOGIN, IF NOT EXISTS
ALTER ROLESupportedChange password, superuser, login
DROP ROLESupportedIF EXISTS
GRANTSupportedGRANT permission ON resource TO role
REVOKESupportedREVOKE permission ON resource FROM role

Ferrosa supports column-level permissions, rate limiting per role, and audit logging to configurable sinks (log file, audit table).

System Keyspaces

system_schema

Standard Cassandra system schema tables for driver compatibility:

system.local

Node metadata including tokens column for driver topology awareness.

system_observability (Ferrosa extension)

Virtual tables backed by live in-memory state, not persisted:

-- Check active connections
SELECT * FROM system_observability.connections;

-- Monitor running queries
SELECT * FROM system_observability.active_queries;

-- Storage engine stats
SELECT * FROM system_observability.storage_stats;

Secondary Indexes

Beyond Cassandra: Ferrosa's secondary index framework goes far beyond Cassandra's SAI or legacy 2i indexes. Eight pluggable index types cover traditional queries, full-text phonetic search, and AI/ML vector similarity — all built into the database with zero external dependencies.

Index types

TypeUSING clauseUse case
B-tree'btree' (default)Ordered range queries and sorted scans
Hash'hash'O(1) equality point lookups
Composite'composite'Multi-column prefix-based lookups
Phonetic'phonetic'Fuzzy name matching (Soundex, Metaphone, Double Metaphone, Caverphone)
FilteredAny + WHEREPartial index over a subset of rows
Vector (HNSW)'vector'Approximate nearest neighbor — graph-based, best query performance
Vector (IVFFlat)'vector'Approximate nearest neighbor — k-means clustering, faster builds

Creating indexes

-- B-tree index (default when USING is omitted)
CREATE INDEX idx_email ON users (email) USING 'btree';

-- Hash index for fast equality lookups
CREATE INDEX idx_user_id ON sessions (user_id) USING 'hash';

-- Composite index across multiple columns
CREATE INDEX idx_name ON users (last_name, first_name) USING 'composite';

-- Phonetic index for "sounds like" matching
CREATE INDEX idx_name_phonetic ON users (last_name)
  USING 'phonetic' WITH OPTIONS = {'algorithm': 'double_metaphone'};

-- Filtered index — only index active users
CREATE INDEX idx_active_email ON users (email)
  USING 'btree' WHERE status = 'active';

-- IF NOT EXISTS is supported
CREATE INDEX IF NOT EXISTS idx_email ON users (email);

-- Drop an index
DROP INDEX idx_email;
DROP INDEX IF EXISTS idx_email;

Vector indexes for AI and similarity search

Ferrosa includes two vector index algorithms for approximate nearest neighbor (ANN) search, supporting AI embeddings, semantic search, and recommendation systems:

-- HNSW index — best query performance, incremental builds
CREATE INDEX idx_embed ON documents (embedding)
  USING 'vector' WITH OPTIONS = {
    'method': 'hnsw',
    'metric': 'cosine',
    'dimensions': '768',
    'm': '16',
    'ef_construction': '200'
  };

-- IVFFlat index — faster builds, good for batch imports
CREATE INDEX idx_embed_ivf ON documents (embedding)
  USING 'vector' WITH OPTIONS = {
    'method': 'ivfflat',
    'metric': 'l2',
    'dimensions': '1536',
    'lists': '100'
  };

Distance metrics

MetricValueUse case
L2 (Euclidean)'l2'Standard distance — smaller = more similar
Cosine'cosine'Angle-based similarity — ideal for text embeddings
Inner product'inner_product'Dot product — larger = more similar

Supports up to 4,096 dimensions (f32) or 8,192 dimensions (f16 half-precision).

Phonetic algorithms

AlgorithmValueBest for
Soundex'soundex'Standard American English names
Metaphone'metaphone'General English pronunciation
Double Metaphone'double_metaphone'Multi-origin names (returns primary + alternate codes)
Caverphone'caverphone'New Zealand English names

How indexes work

Ferrosa indexes are storage-attached — built as companion files alongside SSTables. Indexes are built asynchronously after memtable flush, with zero impact on the write path. This means:

Monitoring index status

-- Check index build status and staleness
SELECT index_name, status, pending_sstable_count, lag_seconds
FROM system_views.secondary_indexes;

-- View index metadata
SELECT index_name, kind, target, options
FROM system_schema.indexes
WHERE keyspace_name = 'myapp';

Multi-node replication

All index DDL (CREATE INDEX, DROP INDEX) replicates automatically in pair mode. Each node independently builds indexes for its local SSTables — no cross-node index coordination needed.

SUBSCRIBE Extension

Ferrosa Extension: SUBSCRIBE is a Ferrosa-specific CQL extension for real-time change streaming. It uses the native CQL v5 framing with a STREAMING response flag (0x10) — existing drivers work unchanged, no client modifications required.

Syntax

-- Subscribe to a table with polling interval
SUBSCRIBE keyspace.table EVERY 5s;

-- Subscribe with push-on-write (change data capture)
SUBSCRIBE keyspace.table DELTA;

-- Subscribe to a SELECT query
SUBSCRIBE SELECT name, email FROM social.users WHERE active = true EVERY 10s;

-- Subscribe to observability tables
SUBSCRIBE system_observability.connections EVERY 5s;

-- Unsubscribe from a specific stream
UNSUBSCRIBE 42;

-- Unsubscribe from all streams
UNSUBSCRIBE;

Modes

ModeSyntaxBehavior
EVERYEVERY 5sServer re-executes the query at the given interval and pushes results
DELTADELTAPush-on-write via SubscriptionObserver in the commit log; only changed rows are sent

Backward compatibility

SUBSCRIBE responses use the standard CQL RESULT opcode (0x08) with the STREAMING flag set in the frame header. Drivers that don't understand the flag will simply see it as a normal result set. The subscription lifecycle is managed server-side — clients don't need to implement any new protocol logic.

Graph (Cypher) Extension

Ferrosa Extension: Cypher graph queries run against CQL tables annotated with graph schema extensions. Queries are sent to a separate HTTP/JSON endpoint on port 7474.

Schema extensions

-- Mark a table as a vertex type
ALTER TABLE social.users
  WITH extensions = {'graph.type': 'vertex', 'graph.label': 'Person'};

-- Mark a table as an edge type
ALTER TABLE social.follows
  WITH extensions = {
    'graph.type': 'edge',
    'graph.label': 'FOLLOWS',
    'graph.source': 'Person',
    'graph.target': 'Person'
  };

Supported Cypher statements

StatementStatusNotes
MATCH ... RETURNSupportedPattern matching, WHERE clause, multi-hop
CREATEParsedParsed; mutate via CQL INSERT (see Cypher reference)
SETParsedParsed; mutate via CQL UPDATE
DELETE / DETACH DELETEParsedParsed; mutate via CQL DELETE
SUBSCRIBE MATCHSupportedReal-time subscription to graph traversals with EVERY/DELTA

Graph SUBSCRIBE

-- Subscribe to a graph traversal
SUBSCRIBE MATCH (a:Person {name: 'Alice'})-[:FOLLOWS]->(b:Person)
RETURN b.name, b.email
EVERY 10s;

-- Push-on-write for graph changes
SUBSCRIBE MATCH (a:Person)-[r:FOLLOWS]->(b:Person)
RETURN a.name, b.name
DELTA;

Not Yet Supported

The following Cassandra features are not yet implemented. They are planned for future releases:

FeatureStatus
Logged batch atomicityPlanned
Query tracingPlanned
Materialized viewsPlanned
Lightweight transactions (LWT)Planned
Note: Even without these features, Ferrosa is fully compatible with standard CQL drivers for core operations: DDL, DML, prepared statements, batches, system keyspaces, and SASL authentication. Most applications migrate without code changes.