Repository navigation
refactor(r13): method calls onto the registry; D3 case mode, P56, P57 (R13 slice 5) - #93
Merged
Merged
Conversation
…P56, D3 (R13 slice 5) Three matrices through both evaluators (default, --case-insensitive, numeric receiver), expectations from DuckDB's contains/starts_with/ends_with/length/ instr/trim family. 33 divergences recorded: P56 (NULL receiver answers FALSE in both evaluators), D3 (WHERE's search methods always ignore case; the registry ignores the switch), and the registry rejecting a numeric receiver (D2 extended to methods). Three DIFFER corpus cases via DuckDB's dot-call syntax; parity contract holds at 212. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ce 5) CONTAINS / INSTR / ENDSWITH as functions share the methods' implementation, so D3 (follow --case-insensitive), P56 (NULL gives NULL) and D2 (a number is its displayed text) apply to them too. 14 entries recorded; WHERE already delegates function calls, so both columns agree. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nd follow --case-insensitive (R13 slice 5) CONTAINS / STARTSWITH / ENDSWITH / INDEXOF / INSTR (and their method forms) read both operands through one `search_text`: NULL gives NULL (P56), any other value is its displayed text (D2), lowercased under --case-insensitive (D3). The mode reaches a function through a new default-implemented `SqlFunction::evaluate_with_case`, and `MethodFunction::evaluate_method` takes it too; the value evaluator's three registry call sites pass it in. LENGTH reads a number as its text as well. Exactly the 27 value-evaluator and function-form matrix entries went FIXED; WHERE's own method arms did not move. Parity moved by exactly one case, select_method_null_receiver (179 -> 180 AGREE / 212). FORMAL examples pass. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e P57 (R13 slice 5) `WHERE s.ToUpper() = 'ABC'` fails the query: WHERE's left-side method arm knows only Length / IndexOf / Trim*. Two matrix rows, a qualified-receiver row, and a GAP corpus case via DuckDB's `label.upper()`. Parity contract holds (213). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ders go (R13 slice 5) A method call as a predicate, and a comparison whatever its left operand, now evaluate through the value evaluator and the registry's method functions. evaluate_binary_op's legacy tail and everything reachable only from it are deleted: the Contains/StartsWith/EndsWith and Length/IndexOf/Trim* arms, WHERE's own column resolver, literal readers, compare_trilean and did-you-mean suggester (~700 lines). The remaining 28 matrix entries went FIXED. Parity moved by exactly the three WHERE cases (P56, P57, D3): 180 -> 183 AGREE / 213. Not caught by the pin: a numeric Trim() receiver. WHERE trimmed its text; the registry's TRIM errored, failing the presidents FORMAL example. TRIM / TRIMSTART / TRIMEND now read a number as its displayed text (D2), pinned. Three tests asserted the old always-case-insensitive rule; rewritten to assert D3 in both modes. No captured example output changed. Contains / Length / StartsWith over trades_100000.csv run at load time, level with LIKE. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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 5: WHERE's hand-rolled method calls move onto the function registry. Every predicate operator and method call in WHERE now evaluates through the value evaluator — one implementation per method, in every clause.
Behaviour changes
Contains/StartsWith/EndsWith/IndexOf(method and function forms) andINSTRfollow--case-insensitivelike=andLIKE— case-sensitive by default. WHERE's.Contains()used to ignore case always; SELECT's never did, even under the switch. Queries relying on WHERE's old behaviour change answer;--case-insensitiverestores it.WHERE NOT label.contains('e')no longer selects NULL labels (both evaluators).WHERE s.ToUpper() = 'ABC'used to fail the query; only Length / IndexOf / Trim* were accepted).n.Contains('5'),n.Trim()).How
SqlFunction::evaluate_with_case(default ignores the mode) carries the switch into a function;MethodFunction::evaluate_methodtakes it; the value evaluator's three registry call sites pass it.search_textreader instring_methods.rsfor the search functions, LENGTH and TRIM*.compare_trileanand did-you-mean suggester deleted.Commits (pin → fix, R10 pattern)
Verification
expander_rewriterssmoke example, which fails identically onmain(unrelated GROUP BY error).Trim()receiver was missed by the pin and caught by thepresidentsFORMAL example; fixed and pinned.Contains,Length() >,NOT StartsWithovertrades_100000.csvall at load time (~2.5 s), level with LIKE.Left for later
Details:
docs/ENGINE_REFACTORING.md§ R13 slice 5; P56, P57, D2, D3 indocs/SQL_PARITY.md.🤖 Generated with Claude Code