Repository navigation
fix(rel): push safe input predicates before required fixed expansion #1241
Description
Problem and measured selection
#1207 candidate 1 identifies a verified planner barrier after the merged storage baseline 5fc68e568893110cca97b0eb2c797d306b264e27. On the existing public eight-route 4097-node/65537-edge fixture, a selective start-property predicate remains above two required fixed expansions. It produces 1,113,889 expansion candidates and scans 8,932,490 edge rows before returning the independently verified 256 paths. An equivalent explicit-WITH prefilter control produces only 272 candidates and scans 80,898 edge rows, with identical full UUID results. Users must not need to rewrite their query to obtain this reduction.
The frozen release control executable (assessment source 9ca395d3785ce9ede9c34b539d1e3479d0d08d05, SHA256 d695553c3e0ebb22cc4ae0db09466843689636159179fb9f478170183ae19505) gives three fresh-process original first-query observations 3.840–4.636 s (median 3.965 s), versus 0.253–0.266 s for the equivalent control. Twelve reused-facade observations are 3.582–4.017 s versus 0.253–0.264 s. These are controls, not an implemented optimization.
For facade open plus five queries, complete separate syscall traces report original read/write 8,149,233,916 / 130,790,402 bytes versus control 232,779,294 / 32,998,383 bytes; no unresolved calls or syscall errors. These are successful syscall bytes, not physical disk I/O. Process CPU is original 31.08–31.47 s versus control 2.09–2.12 s. Observed RSS is original 152,332–153,640 KiB versus control 100,408–101,496 KiB.
Separate regular-file scans across the fixture and private TMPDIR, deduplicated globally by device/inode, observed overlapping allocation original 53,239,808 bytes (11,988,992 private temporary) versus control 53,882,880 (12,632,064 temporary). The control does not meet the initially proposed no-increase temporary ceiling: preserve this cost honestly and require the implementation to resolve or quantify it before acceptance. Requested 5 ms polling actually reached 77.8/72.8 ms gaps; these are sampled observations, not hard bounds, and exclude directories and unlinked-open files.
Bounded repair
Move only eligible start/input predicates across required fixed ExpandNode boundaries while preserving qualified unchanged input references and property joins. The pinned DataFusion 54.1 extension default blocks all output column names; its generic hook checks unqualified names and does not establish volatility/error safety. A blanket output-minus-input name hook is insufficient. Keep edge/destination/mixed predicates residual and preserve optional/variable-length/path boundaries, errors, volatility, nulls, duplicates, ordering and LIMIT.
Debt: development/test-proof. Rust owns behavior. No persisted-format change, compatibility shims, generic optimizer rewrite, new index, or speculative statistics repair.
Acceptance criteria
- The original public query, without a WITH workaround, returns exact independent UUID/schema/value/null/duplicate results and performs first-hop input 1/candidates 16, second-hop input 16/candidates 256; edge rows scanned at most 80,898 on the representative fixture. Establish equality and equivalent range regression coverage with actual execution, not only logical plans.
- Boundary tests cover same property names on different qualified variables, residual destination/edge filters, mixed OR, nulls, optional and variable-length scopes, potentially failing/volatile expressions, duplicate fan-out and ORDER/LIMIT. Preserve cancellation, demand/spill and property-join behavior.
- Freeze executables before comparable measurement. Deterministic syscall and allocation ceilings use the original baseline above. Investigate sampled temporary overlap rather than relabeling it a bound. No added persistent artifacts or mutation/rebuild/replay/compaction work. Observed RSS investigation ceiling 154,948 KiB (baseline maximum plus observed range), not a hard native memory guarantee.
- Repeated latency/CPU evidence, separate from instrumentation: first-query median at most 1,062,367,774 ns; reused-facade median at most 698,343,326 ns; facade-open plus five-query CPU at most 2.51 s. These pre-implementation thresholds derive from control maximum plus original observed range, not a universal percentage; keep noisy timing out of CI assertions. Any threshold revision must precede candidate selection and state its evidence and reason.
- Prove affected public behavior after construction, immediate query, reopen, export, full verification, clean import and subsequent mutation. Preserve exact current-format authentication/corruption refusal, active snapshots and recovery; reuse existing lifecycle fixtures where they directly cover the repair.
- Commit source-bound measurements, correctness boundaries and deterministic budgets; run appropriate repository gates and exact-head CI Gate; focused squash merge and verified closure.
Given selective input predicates and fan-out, when the original public query executes, then rejected start rows do not expand and exact output is unchanged. Given a predicate outside the safe boundary, when planning executes, then it remains in its semantic scope and existing errors/results are preserved.
Relationships
Native blocking child of #1194; selected by #1207, which remains the canonical five-candidate assessment. Prerequisites #1196, #1202, #1203, #1204, #1205 and #1213 are merged/closed. Related closed #966 handled fixed-hop projection, not this predicate barrier; no duplicate open repair found. This issue neither replaces #1207 nor authorizes S24/S26 or a new certification workflow.
Activity
fix(rel): admit total input predicates across fixed expansion (#1241)
fix(rel): schedule predicate movement before projection pruning (#1241)
test(api): prove selective predicate work and portable mutation lifec…
refactor(rel): keep optimizer rule configuration beside its implement…
docs(perf): retain OS I/O counters alongside syscall evidence (#1241)
docs(perf): record complete local validation census (#1241)
fix(rel): push safe input predicates before fixed expansion (#1243)
DecisionNerd commentedon Sep 29, 2026
Evidence relocated from the docs tree (#1625). The 1 file(s) below were committed under
docs/development/as measurement evidence for this issue. They are removed from the tree by #1628 (the #1625 pull request); the repository keeps method and content digests, results live here. Every file remains available at its permalink on commit29a7b34ebe44, and its SHA-256 is recorded next to it.Files (1 total, 823 lines)
docs/development/evidence/input-predicates-1241.jsonsha256:bf31093f99a9911f440736fb60faf7bf523f5117f6e18ecd8baa7c46cd2ec608