Skip to content

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.

  • 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 a GROUP BY hash (#1587); a read-path idiom bundle (de-async, FxHash, OFFSET skip/take, per-partition digest, IN-expansion allocation cuts; #1590); and dropping the table_readers read guard before scanning (#1591).
  • Point-read I/O (C2) — a ReadAt positional-read trait removes the point-read cursor convoy and the per-lookup open(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 cache Set/Map constructors per result conversion (#1448).
  • Cached comparators — derived comparators are cached on SchemaEntry so composite key ordering isn’t rebuilt per comparison (#1709).
  • Byte-bounded result budget — queries now respect a max_result_bytes budget (default 64 MiB). A result that would exceed it fails fast with ResultTooLarge instead of ballooning memory. Add a LIMIT clause 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).
  • 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 id default schema (#1710, and see the breaking changes below).
  • BTI export-sstable partition count is read from the authoritative Statistics.db reader 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).

v0.13.0 ships three breaking changes. See the v0.13 Migration Guide for before/after examples and per-surface details.

  • Python bindings — CQL duration and time now decode to exact, lossless types matching Node, the CLI, and Cassandra: timeint (nanoseconds since midnight), durationcqlite.Duration(months, days, nanos). The old datetime.time / datetime.timedelta mapping 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 fabricated uuid id default schema (#1710).
  • CLI — YAML query output was removed. --out yaml and --format yaml are rejected at parse time; switch to table, json, csv, or parquet (#283).
Terminal window
brew install pmcfadin/cqlite/cqlite # CLI (macOS + Linux)
cargo add cqlite-core # Rust library
pip install cqlite-py # Python
npm install @cqlite/node # Node.js

Full detail in the CHANGELOG, and upgrade notes in the v0.13 Migration Guide.