Repository navigation
refactor(r13): WHERE BETWEEN / IN delegate to the value evaluator (R13 slice 4, part 1) - #87
Merged
Merged
Conversation
…/ IN (R13 slice 4) Before WHERE's BETWEEN and IN arms delegate to the value evaluator: - the P15 raw-window-operand error in every BETWEEN / IN / NOT IN operand position, which the value evaluator would otherwise evaluate quietly; - alias-qualified operands over two columns sharing a name. Latent (join output disambiguates before WHERE, so not reachable from SQL as probed), but WHERE's column fast path throws the resolved index away and looks the bare name up again, and the inner value evaluator has no aliases. Five divergences recorded; the next commit is expected to flip them. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
…uator gets aliases (R13 slice 4) WHERE's column fast path resolved an alias-qualified operand to an index through the ExecutionContext, turned it back into a bare name, and looked that up again - finding the first column of the name, not the one the qualifier picked. The value evaluator WHERE hands expression operands to was built with no aliases, so `i.a + 0` had the same fault from the other side. Now the index is used directly, and the inner evaluator is given the context's aliases, so a column means the same thing whichever of the two resolves it - the precondition for BETWEEN / IN delegating. Latent (join output disambiguates duplicate names first); flips the five recorded divergences. Parity report byte-identical. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Non-interactive mode installs a TRACE subscriber writing to a ring buffer
and a log file, so every `debug!` in `ArithmeticEvaluator::evaluate` - once
per expression node per row, formatting the whole expression with `{:?}` -
was paid in full. It was most of the evaluator's cost: with the filter lowered
(`RUST_LOG=warn`) `WHERE price + 0 > quantity` over trades_100000.csv ran in
load time.
Removed the entry log, the binary-op log (and its now-unused format_value),
column resolution, method proxy and CASE branch logs. Best of 3, ~2.4 s load:
WHERE price + 0 > quantity 5.5 s -> 3.0 s
SELECT price * quantity 4.8 s -> 2.6 s
GROUP BY UPPER(trader) 4.3 s -> 2.6 s
GROUP BY trader 3.7 s -> 2.5 s
Found measuring slice 4: WHERE arms that delegate to this evaluator must not
cost more than the arms they replace. Parity report byte-identical.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
…slice 4) The BETWEEN arm now evaluates through `ArithmeticEvaluator` and reads the answer back with `Trilean::from_value`; `evaluate_between` and its own copy of the AND-over-two-comparisons rule are gone. `evaluate_delegated` is the one crossing every delegated arm will use. The P15 raw-window-operand check stays on WHERE's side (`reject_unlifted_window`, now shared with `evaluate_operand_value`), since the value evaluator would evaluate one quietly. Parity report byte-identical, matrix green (both runs), pins from the first commit hold. `WHERE price BETWEEN 100 AND 500` over trades_100000.csv 3.0-3.2 s -> 2.5-2.7 s. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
…13 slice 4) Both arms now evaluate through `ArithmeticEvaluator` via `evaluate_delegated`; `evaluate_in_list` - WHERE's copy of the OR-over- equalities rule, with an unused `_ignore_case` parameter - is gone. The raw window check covers the probe and every list item, as before. Parity report byte-identical, matrix green (both runs). Over trades_100000.csv: IN 3.6 s -> 3.0 s, NOT IN 3.0 s -> 2.5 s. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
…cost) Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This was referenced Sep 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
R13 slice 4, first part: WHERE's
BETWEEN,INandNOT INarms now delegate to the value evaluator and cross back once, inevaluate_delegated(Trilean::from_value). WHERE's own copies of those rules are deleted.Commits
i.ato the right index, then looked the bare name up again and got the firsta. The inner value evaluator was also built without aliases. Latent: join output renames duplicate columns before WHERE runs, so no SQL probe reached it. Flips the five pins.evaluateformatted the expression at every node of every row. Overtrades_100000.csv(~2.4 s load):WHERE price + 0 > quantity5.5 → 3.0 s,SELECT price * quantity4.8 → 2.6 s,GROUP BY UPPER(trader)4.3 → 2.6 s.docs/ENGINE_REFACTORING.md.Verification
./run_all_tests.shpasses: Rust, Python, all FORMAL examples. One SMOKE failure (expander_rewritersquery 7) also fails the same way on main.Next (slice 4 part 2)
Comparison arms, then LIKE and IS NULL, each pinned first. The operand readers still differ:
TODAYlocal vs UTC,DATETIMEdate vs string,5.0integer vs float, left-side legacy method calls (slice 5), and the LIKE regex cache.🤖 Generated with Claude Code