Pruning must key a literal the way the index stored the value
Symptom#
A filter on a bool field returns no rows on every path that uses the index (View scan, reader), while the same filter over the JSON records keeps the matching ones:
ok == trueover records with"ok": truereturned nothing in View collect, group/count,sink_json,read_linesandread_json.
Cause#
The index build had stored the bool as the integer 1 (the fold event keeps a bool as int64 1/0, and the bloom and zone-map builders saw that integer). Pruning turned the query literal true into the text "true" and looked that up. No chunk's evidence held "true", so every chunk was skipped.
Fix#
Convert each literal to the exact form the build stored before any bloom, postings or zone-map lookup: in dftracer-utils a bool literal becomes "1" or "0" in literal_to_string (index/plan/conditions.cpp). This only widens what a chunk may match; the evaluator still decides the rows. Test every literal type through each pruning path against a scan with the index off.
Evidence#
- dftracer-utils cross-path test
tests/trace/views/test_duql_paths.cpp(2026-09-27) found it: the filter returned 0 of 1 expected rows on all index-backed paths. After the change it returned the expected row on every path, and the prefilter fuzz and prune oracle tests still passed.