Build your own mini table format · Stage 6 of 7
Manifest column stats + file pruning
A query that touches 2 of 10,000 files should open only those 2. The manifest already lists each data file; now record per-column min/max stats at write time, and use them at scan time to skip files that cannot match a filter. This is the whole reason planning is fast on a lakehouse.
Implement
- When you write a data file (
append, and the compacted file in stage 7), record per-column{min, max}in that file's manifest entry. table.scan(filter=(col, lo, hi))takes an inclusive range filter. Before opening a data file, check its stats: if the file's[min, max]forcolcannot overlap[lo, hi], skip the file entirely (don't open it). Then still apply the row-level filter to the files you do open, so the returned rows are exactly those matching the predicate.- Track every data file you physically open in
self.files_opened(a list of keys). The tests read it to prove pruning happened.
The classic bug to avoid
Bounds are inclusive on both ends. A file with max == lo or min == hi
does overlap and must be read. Using strict </> here drops boundary rows —
the tests check exactly that.
Keep stages 1–5 green (an unfiltered scan() still returns everything).
Hints
Hint 1
At write time, compute min/max per column (pyarrow.compute.min/max) and store them in the manifest entry's stats dict.
Hint 2
scan(filter=(col, lo, hi)): for each file, skip it when stats[col].max < lo OR stats[col].min > hi. Only read (and record in files_opened) the survivors.
Hint 3
Bounds are inclusive: a file whose max == lo still overlaps. Use <= / >=, not < / >, or you'll drop boundary rows.
uv run de start LKH-BYO/06-stats-pruning
uv run de test