CQLite v0.14.0
CQLite v0.14.0 — Flight field-readiness
Section titled “CQLite v0.14.0 — Flight field-readiness”Read and query Apache Cassandra 5.0 SSTables through Arrow Flight and Trino — no cluster required. This release takes the Flight read path from working to field-validated: the round-9 field build ran against a live, at-scale Cassandra deployment (validation tracker #2367).
✈️ Field-validated Flight read path
Section titled “✈️ Field-validated Flight read path”- Streaming
do_getscan — the scan path no longer materializes the whole SSTable before the first row. It walks the index lazily, appliesLIMITeffectively, and tears producers down on cancel, so memory stays bounded (#2361). - Parse-once warm registry — the resolve phase stopped re-parsing per request at
multi-million-partition scale. Single-flight parse plus rebind-by-inode removes the
CPU spin that hung
LIMIT,count(*), and point reads (#2383). - Predicate pushdown —
do_getpushesWHERE pk = ?toward a partition point-read or prune instead of a full merge scan (#2207). - Cancellation that works — the snapshot-index reload loop honors cancellation,
so
LIMITqueries no longer hang and the in-flight gauge no longer sticks (#2264, #2157).
✅ Correctness & parity
Section titled “✅ Correctness & parity”- No silent multi-cell collapse — the Flight producer no longer overwrites multi-cell and collection columns through a HashMap (#2324).
- Read-time reconciliation — a multi-generation
SELECTapplies read-time TTL, partition, and range-tombstone visibility (#1849). - TTL round-trips through compaction — the write path honors
USING TTLand per-cell expiration; surviving live TTL cells stay byte-identical after compaction, including complex, collection, and UDT elements (#1743, #2038). - Float ordering matches Cassandra —
Valuecomparison,ORDER BY, andMIN/MAXorder floats as Cassandra does: NaN last,-0.0 < +0.0(#2010, #1870). - No-heuristics hardening — blob decode no longer guesses from a byte pattern; recursion-depth guards and clamped capacities protect the parser (#1630, #1414).
🚀 Performance
Section titled “🚀 Performance”The read, parse, and export hot paths from the audit epics landed: boxed Value
variants (88B → ≤40B), byte-bounded result budgets in place of the 1M-row cliff,
LIMIT/OFFSET pushed into the scan, streaming multi-generation merge and O(1)
aggregates, a key→partition-offset cache, and one-walk zero-copy BTI trie descent
(#1583, #1582, #1577, #1585).
⚠️ Breaking changes
Section titled “⚠️ Breaking changes”- Config schema —
MemoryConfigcollapsed to one real caching knob,block_cache.max_size. The decorativerow_cache,query_cache, andallocatorfields and the unusedCachePolicy::Lfu/Arcvariants were removed; a config that still names them now fails closed on deserialization (#1568). - Public API — the dead SSTable reader stacks flagged by the read-path audit were
deleted:
SchemaAwareReader,ChunkedDataReader,StreamingDecompressor, the duplicate legacyCompressionInfo/ChunkInfoparser, and the streaming half ofCompressionReader. All had zero production consumers (#1597).
Known limitations
Section titled “Known limitations”- Cold first-query-per-table parse cost —
SSTableReader::openparsesIndex.dbsuper-linearly (and twice per open), so the first query against a large table pays a cold parse cost at field scale. Fixed in v0.14.1 (#2385, #2395). - Reads are single-node-bound under RF=N — under concurrency one pod does the work; throughput caps at one node (#2397).
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.jsRust crates and the Python and Node bindings move 0.13.0 → 0.14.0 in lockstep. The
Trino connector (in.mcfad:cqlite-trino) is versioned separately. Full detail in the
CHANGELOG.