Skip to content

v0.17.0 — materialized measure state served the wrong population

Choose a tag to compare

@datumwise datumwise released this 31 Aug 01:11

columna 0.17.0 · columna-core 0.17.0 · columna-server 0.11.0

Two defects in the sketch/witness path were serving a confident wrong number. Both were reproduced under the real runtime before they were touched, and both now carry standing tests verified to fail against the pre-fix source.

Fixed

A carved universe was not carved in materialized state. _build_base_sketches delivered base rows and never confined them — no _confine, no grain augmentation for the levels the universe predicate reads, and the where it forwarded was the query WHERE rather than the universe predicate. A distinct count over a restricted universe therefore served the unconfined population, while its own disclosure asserted [over <universe>]: the frame claimed the confined population and delivered the other one. In the shipped reproduction the engine returned 3 where the declared carve admits 1.

On the same universe a sum confined correctly, so one Manifold answered two different populations depending on the operator. Both the eager published witness and the lazy fallback build were wrong identically — one shared defect, not a materialization bug.

Confinement now happens on the raw rows, before hll_count, because an HLL sketch cannot be filtered afterwards: an out-of-universe value that reaches the carrier is in it permanently.

Unknown data identity was fail-OPEN on the witness store. WitnessStore.fresh compared None == None and reported a stale witness as current. A real data mutation stayed invisible — 2 served against a ground truth of 3, at zero backend fetches, with no staleness disclosure. The result cache, built on the same identity primitive, was fail-CLOSED throughout: one primitive, two opposite polarities.

fresh() now refuses an unknown or unversioned identity, and put() refuses to store an unversioned witness at all. Unknown identity closes storage, not merely reuse — a witness stored without a version can never be shown stale, so storing one converts a missing identity into a permanent claim of freshness.

Witness currency now uses the complete computation dependency set. It was data_version(home_table) while the result cache on the same request used data_version_of(computation_tables(...)), so a change to a universe-predicate provider re-derived the monoid answer and left the witness "fresh".

These three shipped together deliberately. The currency defect was latent only because the confinement defect existed — the witness never read the predicate, so its content genuinely depended on the home table alone. Fixing confinement alone would have converted a cancelled defect into an active staleness bug.

Changed — user-visible strings

Four refusal and clarification strings reachable at runtime named a commercial tier that does not exist. Each was reclassified individually; there was no global replacement.

surface was now
fan-out clarify WITH allocation — … [Pro] [ROADMAP — not available in this build]
windowed-scan refusal windowed scans are Pro in this build not implemented in this build [ROADMAP]
scan alternative windowed scans (rolling_*) [Pro] … [ROADMAP]
unknown operator (Core registry: …); custom operators are Pro (registry: …); custom operators are [ROADMAP]

The operator registry is the shared extension point, not a Core/Pro seam. Custom operators are ROADMAP — unbuilt, not withheld. Consumers matching on these strings should read the wire code and materiality fields instead; the codes did not change.

Also

The columna-core README is repaired: it no longer heads itself 0.7.8-core (nine minor versions stale, in the heading PyPI renders), no longer describes capabilities as "deliberately out (Pro)", and no longer documents a FAMILY { <agg> [: <tier>] } clause that the parser rejects with bad FAMILY member.

Why minor and not patch: served values change, reuse semantics change, and four user-visible strings change.

columna-server stays at 0.11.0 — its floor is satisfied and none of its own source moved.