CQLite v0.13.0
CQLite v0.13.0 — the performance release
Section titled “CQLite v0.13.0 — the performance release”Read and query Apache Cassandra 5.0 SSTables faster — no cluster required. This release is all about the read path: less work per query, fewer syscalls per lookup, and one I/O per compressed chunk.
🚀 Performance
Section titled “🚀 Performance”- Read-path constant-factor bundle (Epic E) — a sweep of query-engine hot-path
cleanups: schema
Arc, single projection, cached sort keys, a plan cache, and aGROUP BYhash (#1587); a read-path idiom bundle (de-async,FxHash, OFFSET skip/take, per-partition digest, IN-expansion allocation cuts; #1590); and dropping thetable_readersread guard before scanning (#1591). - Point-read I/O (C2) — a
ReadAtpositional-read trait removes the point-read cursor convoy and the per-lookupopen(2)(#1573). - One payload + CRC read per compressed chunk — the E3 A5 read-path bundle collapses each compressed chunk down to a single payload+CRC read (#1585).
- Node bindings throughput — batch-fetch streaming rows per async task (#1443),
move (not deep-clone) row values in
executeNative(#1447), and cacheSet/Mapconstructors per result conversion (#1448). - Cached comparators — derived comparators are cached on
SchemaEntryso composite key ordering isn’t rebuilt per comparison (#1709).
🧰 New APIs
Section titled “🧰 New APIs”- Byte-bounded result budget — queries now respect a
max_result_bytesbudget (default 64 MiB). A result that would exceed it fails fast withResultTooLargeinstead of ballooning memory. Add aLIMITclause or switch to the streaming query API (streaming is not subject to the budget) to recover (#1582). Database.refresh()— re-discover SSTables written by Cassandra or another process after the database was opened. It is explicit-only and atomic, and reports how many tables were scanned and how many readers were added/removed (#1749).
✅ Correctness & no-heuristics
Section titled “✅ Correctness & no-heuristics”- No byte-pattern type guessing — the raw-decode path no longer infers a value’s type from its byte pattern; blobs that happened to look like other types are returned faithfully as blobs, per the no-heuristics mandate (#1630).
- Unknown-table reads fail honestly rather than returning a fabricated
uuid iddefault schema (#1710, and see the breaking changes below). - BTI
export-sstablepartition count is read from the authoritativeStatistics.dbreader instead of a derived estimate (#1622). - Chunk-CRC corruption surfaces on point lookups instead of silently proceeding (#1411).
- Full-scan no longer issues duplicate scans — bounded streaming replaces the old 4× duplicate table scan on the full-scan path (#1691).
⚠️ Breaking changes
Section titled “⚠️ Breaking changes”v0.13.0 ships three breaking changes. See the v0.13 Migration Guide for before/after examples and per-surface details.
- Python bindings — CQL
durationandtimenow decode to exact, lossless types matching Node, the CLI, and Cassandra:time→int(nanoseconds since midnight),duration→cqlite.Duration(months, days, nanos). The olddatetime.time/datetime.timedeltamapping was lossy (#1450). - Discovery-driven flows — reading a table with no registered or discovered schema
now returns an error (
Table schema not found: {table}) instead of a fabricateduuid iddefault schema (#1710). - CLI — YAML query output was removed.
--out yamland--format yamlare rejected at parse time; switch totable,json,csv, orparquet(#283).
Get it
Section titled “Get it”brew install pmcfadin/cqlite/cqlite # CLI (macOS + Linux)cargo add cqlite-core # Rust librarypip install cqlite-py # Pythonnpm install @cqlite/node # Node.jsFull detail in the CHANGELOG, and upgrade notes in the v0.13 Migration Guide.