The shared boundary for the hosted search API. A (pattern, fixed, ignore_case, pcre, mode) spec lowers once into an immutable matcher, and
every face — cold CLI, warm session, FFI, language bindings — draws its two
answers from that one form: the sound trigram prefilter that prunes index
candidates, and the per-document match / line-count decision. Neither caller
learns which engine backs the query, so none of them can drift on what
matches or on which literals are safe to skip.
The stronger prunings are drawn from here too, and by one call. winnow
returns the conjunctive cover plan and the crest sieve's forced swell off a
single lower.parse, because the parse is the expensive half and both faces
need both. That it is one function rather than two is a soundness property,
not a tidiness one: cold's Writ.compile and the resident session's
gather.winnowFor must agree on what a pattern forces, and the way to
guarantee that is to give them nothing to disagree from.
query.zigownsCompiledQuery: the lowering, theScratchgrain a walk worker owns, and the match/count primitives over the-Fliteral fast path or the engine-neutralMatcher.prefilter.zigderives the literals warm and cold must share verbatim — required/alt cover, the case-variant OR-set, the-F -iescape — pluswinnow, which hands both faces the cover plan and the crest swell from one parse. The caseless fold window it re-exports rather than owns: that rule moved down beside the caseless SIMD kernel it guards (scan/simd.zig), so the regex compiler can mine its own gate without importing this tier.cover.zigbuilds the conjunctive cover: the whole boolean query a pattern forces, not just its best single literal (see below).word.zigis the ripgrep-wword-boundary rule as a post-match predicate (wordOkplus the literal / regex word-span scans), over the same\boracle the engine uses.query_test.zigchecks compile / prefilter / match cases against an independent oracle.cover_test.zigbrute-forcesmatched ⇒ never prunedover an exhaustively enumerated document space, plus the reachability cases each lowering rule exists for.zero_width_test.zigpins the two zero-width match sequences this package reports —Cursor's library sequence andquery's walk's grep sequence — each against its own outside bar (Pythonre/rust-regex/JS for one, ripgrep for the other), so neither can be "fixed" into the other.word_rule_test.zigdifferentials the-wrule acrossquery's walk andglean'sCursor, on both the linear and PCRE2 backends, so a host that reads one after the ABI moved from the first to the second gets the same spans either way.
prefilter.zig and word.zig are private to this folder, imported only by
query.zig, which re-exports what callers need so the surface stays
query.<name>. Both are soundness code: a prefilter that over-claims
silently skips a real match, so neither may be inlined into a caller that
could relax it.
This folder decides which rung to take; the folders beside it are the
rungs. Fixed -F goes to ../scan/ SIMD, everything else compiles through
../regex/, and PCRE2 is entered only when -P / --engine auto demands
lookaround or backreferences. Adding a rung means teaching query.zig to
choose it, never teaching a caller to reach past this seam.
One literal is not what a pattern proves. prefilter.zig answers the
one-literal question: which single literal, or single alternation cover, is
mandatory? That question throws away most of what a pattern proves.
if\s+err\s*!=\s*nil forces four disjoint literal runs and the one-literal
planner keeps the longest. func\s+\w+\( forces func immediately followed
by a whitespace byte, but \s is not a singleton, so the run stops at
func and the adjacency, the most selective fact in the pattern, is never
asked of the index.
cover.zig answers the whole question, returning a conjunction of
disjunctions of conjunctions, the shape trigram.Index.queryPlan evaluates
and the shape csearch's regexp/query.go builds:
plan ≔ clause ∧ clause ∧ … every clause is necessary
clause ≔ atom ∨ atom ∨ … some atom holds
atom ≔ literal ∧ literal ∧ … all of these literals' trigrams present
Three things make it more than csearch's tree, each measured in Layer L:
- A small byte class is a choice point, not a wall. A run of adjacent
positions is carried across the whole concat spine and survives a
partially known node by folding in that node's provable head set.
func\sbecomes the six 5-byte alternatives rather thanfunc;https?://becomes the two whole schemes rather than a 3-byte boundary trigram, becausex?is read as the finite set{ε, x}, the one repetition whose language is finite. - Sliding windows keep every provable constraint. When a segment's
cross-product overflows the atom ceiling, every start position is tried
at the shortest extent clearing the trigram floor.
[0-9a-f]{8}-[0-9a-f]{4}has a 16¹²-way whole product, but three of its windows straddle the dash and each fits; csearch takes one of the three and stops. Their conjunction is what a cost-ordered evaluator can afford to ask. - Emitting more is free, because the index picks. A syntactic planner
must guess which constraint is worth evaluating.
queryPlanknows the real posting cardinality of every trigram, so this module's job is to emit every sound necessary condition and let the measured cost model order them and decline the ones that cost more than they prune. Widening the choice never widens the answer.
Every clause returned is a necessary condition: if a document matches, it
contains, for every clause, all the literals of at least one of that
clause's atoms. A clause is emitted only when every atom in it is filterable
(each literal ≥ 3 bytes); one unwitnessable alternative would make the
disjunction vacuous, and a vacuous clause evaluated as if it were real elides
matches. That is why panic|0x yields no plan at all rather than a plan
built on panic.
Limits are cost bounds, never soundness bounds: exceeding any of them makes
the planner emit a weaker clause or none, which only ever widens the
candidate set. Their defaults are the measured knees of the Layer-L sweep
(--cover-class / --cover-atoms / --cover-clauses), not asserted
constants.
cover_test.zig proves the contract by running the production matcher over
every string in an enumerated document space, in the discipline of the
crest Sieve Theorem, never by arguing about the lowering.